since i googled for the last 2 days and still can't figure it out:
I'm working with Unity and c#. I have a http client which sends async get requests to my local server. This server is set to always wait a certain amount of time until it sends a response. This is to simulate some behavior where the real server just doesn't answer.
For this example, let's say my server waits 20 seconds before sending a response. My client is set to timeout in 3 seconds.
Now i assumed that an error would be thrown after 3 seconds because of the timeout and the request is canceled but that's not the case. The error is thrown after the client receives a response, which is after 20 seconds.
The problem is that the "real" server doesn't answer every request. Maybe because i send requests to fast? Anyway, this requests are never answered and live forever.
My code for the client is as follow (C# in Unity):
private HttpClient _client = new HttpClient(); // create the http client
public void Start()
{
_client.BaseAddress = new System.Uri("http://127.0.0.1:8000"); // set base url
_client.Timeout = new System.TimeSpan(0, 0, 0, 0, 3000); // set the timeout to 3 seconds, could be 500 ms
GetRequest();
}
private async Task GetRequest()
{
try
{
var httpResponse = await _client.GetAsync("/somepath_doesnt_matter"); // send request and await response
string result = await task.Content.ReadAsStringAsync(); // read the string
Debug.Log("Done"); // all is good
} catch (Exception e)
{
Debug.Log(e.Message); // canceled <--- prints after 20 seconds, not 3
}
}
ps: using a CancellationTokenSource, setting it to timeout after 3 seconds and passing a token to the GetAsync function results in the same behavior.
Is there a way to "immediately" throw the error after the timeout and cancel the task?
Edit: here ist he full file: https://pastebin.com/WJQjmngt
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using UnityEngine;
public class Example1 : MonoBehaviour
{
private HttpClient _client = new HttpClient();
void Start()
{
_client.BaseAddress = new System.Uri("http://127.0.0.1:8000");
_client.Timeout = new System.TimeSpan(0, 0, 0, 0, 3000);
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
GetRequest();
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
}
private async Task GetRequest()
{
try
{
CancellationTokenSource cts = new CancellationTokenSource();
cts.CancelAfter(3000);
var task = await _client.GetAsync("/somepath", cts.Token);
string result = await task.Content.ReadAsStringAsync();
Debug.Log("GOT:\n" + result);
}
catch (Exception e){
Debug.Log("EXCEPTION ============================");
Debug.Log(e.Message);
}
}
}
Edit2: Seems like Unity do things different for whatever reason. I wrote the code in VS Console Application and it canceled as expected. In Unity however it waits for the response to throw the error. I guess i go to unity forums to ask whats wrong. Here the code and the results if someone is interested: pastebin.com/Tk4KHNmh