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);
}
}
我簡化了代碼,現在它是這樣的。第一個等待快速轉移控制到下一個等待,然後第二個等待表現如我所料,最後輸出「完成」。但我不知道這裏有什麼不同。
更新:千萬記住示例代碼是一個不好的做法。你可以read this post for more information
和一個朋友建議不同的是,
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表達式表示。我的意思是,沒有像'新的異步行動(...)'的權利?
更新:
我想這被認爲是相當於Task.Run(動作行爲)和東西Task.Factory.StartNew(動作動作)再次更改:
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 void',並且它不是用於事件處理程序的時候,你可能是在做一些錯誤的事情。 'async'應該總是返回一個'Task'。 –