我想运行GetAnswerToLife方法等待5秒然后打印210,而“for loop”正在打印数字。但是下面的代码只打印for循环,我无法使这个异步方法工作。在任何地方都看不到210。这里有什么我想念的吗?
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication30
{
internal class Program
{
private static async Task<int> GetAnswerToLife()
{
await Task.Delay(5000);
int answer = 21 * 10;
return answer;
}
private static void Main(string[] args)
{
for (int i = 0; i < 100; i++)
{
Console.WriteLine(i);
Thread.Sleep(100);
}
int a = GetAnswerToLife().Result;
Console.WriteLine(a);
}
}
}
答案 0 :(得分:2)
它可以工作,但它们不是异步工作的。循环之后 在打印210之后完成打印。我想要它循环 和其他方法同时开始。
我认为你将异步工作与并行性混淆。异步正在工作,但没有阻塞线程,一旦你的线程命中await
它实际上被释放到线程池做一些其他工作,同时等待await
之后的语句来评估,只有在这继续执行。
并行性是工作并行完成的地方,因此是行动的名称。
以此为例。
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp1
{
internal class Program
{
private static void Main(string[] args)
{
Parallel.Invoke(PrintLoop, async () => Console.WriteLine(await GetAnswerToLife()));
}
public static void PrintLoop()
{
for (int i = 0; i < 100; i++)
{
Console.WriteLine(i);
Thread.Sleep(100);
}
}
public static async Task<int> GetAnswerToLife()
{
await Task.Delay(5000);
return 21 * 10;
}
}
}
现在210将被打印在数字1和100之间,这是不同的,我认为这是你最初想要的。
关于异步操作的@Stephen Cleary explanations实际上不在图表中,你绝对应该检查进一步的读数。答案 1 :(得分:-1)
您在循环后调用GetAnswerToLife
。显然,它将在循环之后执行。
如果您希望在循环的同时计算生命的答案,请在循环开始之前调用它:
private static async Task<int> GetAnswerToLife()
{
await Task.Delay(5000);
int answer = 21 * 10;
Console.WriteLine(answer);
return answer;
}
private static void Main(string[] args)
{
var answering = GetAnswerToLife();
for (int i = 0; i < 100; i++)
{
Console.WriteLine(i);
Thread.Sleep(100);
}
// Calling .Result will ensure the answer has been calculated
int a = answering.Result;
}
我还改变了你对生活实现的回答,所以它在控制台中输出答案,以便在完成计算时知道答案,而不是在循环结束时。