[英]Visual Studio - program ends before asynchronous tasks can finish - C#
對此可能有一個簡單的答案,我只是找不到它,而且是C#的新手。
使用Visual Studio,我編寫了一個函數,該函數將文本異步地寫入文件(使用async / await,並且不返回任何內容),但是在程序的結尾處調用了該函數(我正在對其進行測試),因此,現在要await
,程序將從我從中調用函數的位置(在Main的結尾處)繼續執行,而文本正忙於異步寫入文件。
我的問題來了,當Main結束時,程序完成並退出所有其他異步任務,甚至沒有任何東西可以寫入文件(因為在它實際寫入文件之前,必須經過整個過程) 。 我可以讓Main sleep
一兩秒,但是我寧願更喜歡知道如何等待所有后台異步任務完成后再繼續(而不在Main中使用另一個await / async)。
我知道您可能在想為什么我不讓它同步,因為它在程序的末尾(我正在用它進行測試),但是我需要這種方式,並且想知道如何做到這一點。
void Main(string[] args)
{
try
{
throw new Exception("This is an error\n");
}
catch (Exception ex)
{
LogError.ToFile(ex);
}
//need code here to wait for background processes to finish before ending
}
public class LogError
{
static public void ToFile(Exception excep)
{
Task.Run(() => LogErrorToFile(excep));
}
static public async Task LogErrorToFile(Exception excep)
{
//writes to file using await
}
}
謝謝。
從C#6.0開始,您可以在catch
塊中使用await
;從C#7.0 / 7.1開始,您可以使用async Main
因此您的代碼可以重寫為此
async void Main(string[] args)
{
try
{
throw new Exception("This is an error\n");
}
catch (Exception ex)
{
await LogError.LogErrorToFile(ex);
}
}
如果無法使用,則需要公開使用的Task
並等待其完成,或者使用某種同步機制,例如ManualResetEvent
。
這是因為您不必等到任務完成。 使用Task.Wait
等待任務完成。 或Task.WaitAll
用於等待多個任務的完成。 為此,您必須收集緩沖區中的所有任務,例如List<Task>
void Main(string[] args)
{
try
{
throw new Exception("This is an error\n");
}
catch (Exception ex)
{
LogError.ToFile(ex);
}
LogError.WaitForCompletion();
//need code here to wait for background processes to finish before ending
}
public class LogError
{
private static Task _tasks = new List<Task>();
static public void ToFile(Exception excep)
{
_tasks.add(Task.Run(() => LogErrorToFile(excep)));
}
static public async Task LogErrorToFile(Exception excep)
{
//writes to file using await
}
public static void WaitForCompletion() {
Task.WaitAll(_tasks);
}
}
該代碼不適用於生產,因為_tasks
可以在其中累積許多已完成的任務。 僅將其用作思考的示例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.