Reputation: 73
private async Task<string> httpClient(CancellationToken cancelToken)
{
HttpClient hc = new HttpClient();
hc.Timeout = new TimeSpan(0, 0, 10);
//Task.Delay(5000).Wait(); using this one, it blocks the UI thread
//await Task.Delay(5000); using this one, it doesn't execute the task after delay
if (cancelToken.IsCancellationRequested)
{
return null;
}
HttpResponseMessage response = await hc.GetAsync(new Uri("http://google.com/"));
response.EnsureSuccessStatusCode();
string responseData = await response.Content.ReadAsStringAsync();
return responseData;
}
This is my async task and I have an issue trying to use delay inside of it. I have tried two methods and both seem to cause an issue with the task. Tried researching but couldn't find a way to fix my issue. Any help is appreciated
Other part of the code:
private async void Test()
{
string response = await httpClient(token);
Console.WriteLine("response: " + response);
}
private void button1_Click(object sender, EventArgs e)
{
Task t = new Task(Test);
t.Start();
Console.WriteLine("task started");
t.Wait();
Console.WriteLine("task finished");
}
Upvotes: 2
Views: 77
Reputation: 1064204
The problem is here:
private async void Test()
{
string response = await httpClient(token);
Console.WriteLine("response: " + response);
}
As soon as you've made something async void
you've completely removed any ability to track status. Your new Task(Test);
is using new Task(Action)
, which will report completion as soon as the code first returns to the caller - i.e. at the first non-complete await
(in your case: the Task.Delay
). To do what you want, you should really be using the Task.Run(Func<Task>)
API (or avoiding Task.Run
/ Task.Start
completely, relying on the async plumbing itself), with a private async Task Test()
method.
Your event handler could then be:
private async void button1_Click(object sender, EventArgs e)
{
Console.WriteLine("about to start task");
var t = Task.Run(Test);
Console.WriteLine("task started");
await t;
Console.WriteLine("task finished");
}
or to avoid the extra thread (as noted by Nkosi):
private async void button1_Click(object sender, EventArgs e)
{
Console.WriteLine("about to start task");
var t = Test();
Console.WriteLine("task started");
await t;
Console.WriteLine("task finished");
}
Upvotes: 3