簡體   English   中英

Visual Studio-程序在異步任務可以完成之前結束-C#

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM