[英]Call async method after another async method is finished in C#
我想在步驟 1 完成后調用 step2 方法。 使用下面的代碼,方法步驟 1 和步驟 2 並行執行。 當然,我需要它們是異步的,這樣它們就不會阻止第 3 步的執行。
using System;
using System.Threading;
using System.Threading.Tasks;
namespace test
{
internal class Program
{
static void Main(string[] args)
{
async void step1()
{
await Task.Run(() =>
{
Thread.Sleep(2000);
Console.WriteLine("step 1");
});
}
async void step2()
{
await Task.Run(() =>
{
Thread.Sleep(5000);
Console.WriteLine("step 2");
});
}
void step3()
{
Console.WriteLine("step 3");
}
step1();
step2();
step3();
// the code below is not working but just and idea
// what I want to make. If it at all posible
// step1().step2()
// step3()
Console.ReadLine();
}
}
}
任何幫助將不勝感激。 請記住,我是 C# 的初學者!
編輯:
我知道即使使用這段代碼我也可以獲得最終結果。
void step1() { Thread.Sleep(2000); Console.WriteLine("step 1"); } void step2() { Thread.Sleep(5000); Console.WriteLine("step 2"); } void step3() { Console.WriteLine("step 3"); } step3(); step1(); step2();
即使根本沒有異步/等待。
這個問題的重點是做一個小的概念驗證應用程序,即使代碼是這樣設置的:
step1(); step2(); step3();
最后設置 step3() 的地方將首先執行,因為沒有延遲,而且 step2() 必須等待 step1() 完成。
這完全有可能在 C# 中使用異步/等待。我認為這可以通過 javascript 中的承諾來完成。
如果您將Main
方法(以及step1
和step2
)更改為async Task
而不是void
(或async void
),您將能夠等待您的方法。
static async Task Main(string[] args)
{
async Task step1()
{
await Task.Run(() =>
{
Thread.Sleep(2000);
Console.WriteLine("step 1");
});
}
async Task step2()
{
await Task.Run(() =>
{
Thread.Sleep(5000);
Console.WriteLine("step 2");
});
}
void step3()
{
Console.WriteLine("step 3");
}
step3(); // You can put step3 here if you want it to run before step1 and step2.
await step1();
await step2();
Console.ReadLine();
}
我建議您查看這篇 Microsoft 文章,以更好地了解async Task
與async void
。
對於異步方法的工作原理可能存在誤解。 所有異步方法開始同步運行,就像任何其他方法一樣。 當await
作用於未完成的Task
時,奇跡就會發生。 此時,該方法向調用方法返回一個新的不完整Task
(或者如果它是void
返回任何內容,這就是為什么您應該避免使用async void
)。
因此,如果您首先調用step1()
,那么step1()
將首先開始執行 - 沒有辦法解決這個問題。 但是當step1()
命中await Task.Run(...)
時,它返回並且Main
方法繼續執行。 到那時,您可以決定要做什么。 你想等到step1()
完成還是 go 做其他事情?
如果需要,代碼如下所示:
step1()
首先開始執行。step2()
僅在step1()
完成后才開始。step3()
在step1()
開始后盡快執行,但不等待step1()
完成。static async Task Main(string[] args)
{
async Task step1()
{
Console.WriteLine("step 1 starting");
await Task.Run(() =>
{
Thread.Sleep(2000);
Console.WriteLine("step 1 done");
});
}
async Task step2()
{
Console.WriteLine("step 2 starting");
await Task.Run(() =>
{
Thread.Sleep(5000);
Console.WriteLine("step 2 done");
});
}
void step3()
{
Console.WriteLine("step 3");
}
var step1task = step1();
step3();
await step1task;
await step2();
Console.ReadLine();
}
output 是:
step 1 starting
step 3
step 1 done
step 2 starting
step 2 done
如果您希望step3()
在step1()
甚至開始執行之前執行,那么您需要先調用step3()
- 沒有辦法繞過它。
如果約束是
step1();
step2();
step3();
那么答案是這是不可能的。
除非您可以控制步驟中的代碼,並執行線程信號以防止步驟 2 在步驟 1 結束之前開始。 閱讀有關 ManualResetEvent 的信息。
static void Main(string[] args)
{
var mre = new ManualResetEvent(false);
void step1()
{
Task.Run(() =>
{
Thread.Sleep(1000);
Console.WriteLine("step 1");
mre.Set();
});
}
void step2()
{
Task.Run(() =>
{
mre.WaitOne();
Console.WriteLine("step 2");
});
}
void step3()
{
Console.WriteLine("step 3");
}
step1();
step2();
step3();
Console.ReadLine();
}
放棄異步,這不是你想的那樣。 使用 ContinueWith
Task step1()
{
return Task.Run(() =>
{
Thread.Sleep(2000);
Console.WriteLine("step 1");
});
}
Task step2()
{
return Task.Run(() =>
{
Thread.Sleep(5000);
Console.WriteLine("step 2");
});
}
void step3()
{
Console.WriteLine("step 3");
}
var task = step1()
.ContinueWith(x => step2());
step3();
task.Wait();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.