32 .net c# task wait task-parallel-library
我想向服务器发送请求并处理返回的值:
private static string Send(int id)
{
Task<HttpResponseMessage> responseTask = client.GetAsync("aaaaa");
string result = string.Empty;
responseTask.ContinueWith(x => result = Print(x));
responseTask.Wait(); // it doesn't wait for the completion of the response task
return result;
}
private static string Print(Task<HttpResponseMessage> httpTask)
{
Task<string> task = httpTask.Result.Content.ReadAsStringAsync();
string result = string.Empty;
task.ContinueWith(t =>
{
Console.WriteLine("Result: " + t.Result);
result = t.Result;
});
task.Wait(); // it does wait
return result;
}
Run Code Online (Sandbox Code Playgroud)
我使用Task得当吗?我不这么认为,因为该Send()方法string.Empty每次都Print返回,同时返回正确的值.
我究竟做错了什么?如何从服务器获得正确的结果?
Ken*_*Ito 31
您的Print方法可能需要等待继续完成(ContinueWith返回您可以等待的任务).否则,第二个ReadAsStringAsync结束,该方法返回(在继续中分配结果之前).您的send方法中存在同样的问题.两者都需要等待继续以始终如一地获得您想要的结果.类似于下面
private static string Send(int id)
{
Task<HttpResponseMessage> responseTask = client.GetAsync("aaaaa");
string result = string.Empty;
Task continuation = responseTask.ContinueWith(x => result = Print(x));
continuation.Wait();
return result;
}
private static string Print(Task<HttpResponseMessage> httpTask)
{
Task<string> task = httpTask.Result.Content.ReadAsStringAsync();
string result = string.Empty;
Task continuation = task.ContinueWith(t =>
{
Console.WriteLine("Result: " + t.Result);
result = t.Result;
});
continuation.Wait();
return result;
}
Run Code Online (Sandbox Code Playgroud)
它等待client.GetAsync("aaaaa");,但不等待result = Print(x)
尝试 responseTask.ContinueWith(x => result = Print(x)).Wait()
- 编辑 -
Task responseTask = Task.Run(() => {
Thread.Sleep(1000);
Console.WriteLine("In task");
});
responseTask.ContinueWith(t=>Console.WriteLine("In ContinueWith"));
responseTask.Wait();
Console.WriteLine("End");
Run Code Online (Sandbox Code Playgroud)
以上代码不保证输出:
In task
In ContinueWith
End
Run Code Online (Sandbox Code Playgroud)
但这样做(见newTask)
Task responseTask = Task.Run(() => {
Thread.Sleep(1000);
Console.WriteLine("In task");
});
Task newTask = responseTask.ContinueWith(t=>Console.WriteLine("In ContinueWith"));
newTask.Wait();
Console.WriteLine("End");
Run Code Online (Sandbox Code Playgroud)
一个回答标题的干净示例
string output = "Error";
Task task = Task.Factory.StartNew(() =>
{
System.Threading.Thread.Sleep(2000);
output = "Complete";
});
task.Wait();
Console.WriteLine(output);
Run Code Online (Sandbox Code Playgroud)