class Program
{
static void Main(string[] args)
{
var a = new A();
var result = a.Method();
Console.Read();
}
}
class A
{
public async Task<string> Method()
{
await Task.Run(new Action(MethodA));
await Task.Run(new Action(MethodB));
return "done";
}
public async void MethodA()
{
for (var i = 0; i < 10; i++)
{
Console.WriteLine("MethodA" + i);
await Task.Delay(1000);
}
}
public async void MethodB()
{
for (var i = 0; i < 10; i++)
{
Console.WriteLine("MethodB" + i);
await Task.Delay(1000);
}
}
}
我认为这里的期望是先输出MethodA1,MethodA2...MethodA9,然后再开始输出MethodB1...MethodB9。但似乎不是这样。有人能解释一下吗?谢谢!
编辑:
谢谢回复。实际上我知道如何输出正确的结果,但是我想知道为什么我的代码表现得奇怪,因为我认为它与我的异步/等待的知识相违背。
class A
{
public async Task<string> Method()
{
await Task.Run(new Action(MethodA));
await Task.Run(async () => {
for (var i=0;i<10;i++)
await Task.Delay(100);
Console.WriteLine("should output before done");
});
return "done";
}
public async void MethodA()
{
var returnString = string.Empty;
for (var i = 0; i < 10; i++)
{
await Task.Delay(200);
}
Console.WriteLine("MethodA " + Thread.CurrentThread.ManagedThreadId);
}
}
我简化了代码,现在它是这样的。第一个await快速将控制权转移到下一个await,然后第二个await表现出我期望的行为,最后输出了"done"。但我不知道这里有什么区别。 结果输出
更新:请记住,示例代码是一种不好的实践。您可以阅读此文章获取更多信息
我的一个朋友认为它们之间的区别在于
await Task.Run(new Action(MethodA));
并不等同于
await Task.Run(async () => {
for (var i=0;i<10;i++)
await Task.Delay(100);
Console.WriteLine("should output before done");
});
前者以同步方式调用'methodA',而后者是正确的异步调用。但仍然让我感到困惑,因为如果这是真的,那么异步操作只能由lambda表达式表示。我的意思是,没有像'new async Action(...)'这样的东西,对吧?
更新:
我尝试了Task.Factory.StartNew(Action action),它被认为等效于Task.Run(Action action),然后事情又改变了:
class A
{
public async Task<string> Method()
{
await Task.Factory.StartNew(new Action(MethodA));
await Task.Factory.StartNew(async () => {
for (var i=0;i<10;i++)
await Task.Delay(100);
Console.WriteLine("should output before done");
});
return "done";
}
public async void MethodA()
{
for (var i = 0; i < 10; i++)
await Task.Delay(200);
Console.WriteLine("MethodA");
}
}
我猜我需要更多的帮助...
async
应该始终返回一个Task
。 - Bradley Uffner