首頁 > 後端開發 > C++ > 如何在C#中同步運行異步任務方法?

如何在C#中同步運行異步任務方法?

DDD
發布: 2025-02-01 07:16:08
原創
888 人瀏覽過

How to Synchronously Run an Async Task Method in C#?

如何在 C# 中同步運行異步 Task<T> 方法?

在異步編程中,方法通常定義為異步任務 (Task<T>) 以提高應用程序的性能和響應能力。但是,在某些情況下,您可能需要同步執行異步方法,以進行調試或測試。

同步運行異步方法的幾種方法

一種方法是使用 Task.Wait() 方法,該方法會阻塞調用線程,直到任務完成。但是,在某些情況下,這會導致 UI 凍結和性能問題。

另一種選擇是使用 Task.RunSynchronously() 方法。雖然聽起來它會同步運行任務,但如果任務沒有綁定到委託,它實際上會拋出異常。

最後,您可以使用涉及調度程序幀的解決方法。創建一個新的 DispatcherFrame,啟動它,並在 lambda 表達式中等待任務。任務完成後,將調度程序幀的 Continue 屬性設置為 false 以停止調度程序泵。

一個可靠的解決方法

一個更強大的解決方案是使用同步上下文,該上下文會泵送消息,直到任務完成。這是一個實現此解決方法的類:

<code class="language-csharp">public static class AsyncHelpers
{
    /// <summary>
    /// 同步执行具有 void 返回值的异步 Task 方法。
    /// </summary>
    /// <param name="task">要执行的 Task 方法。</param>
    public static void RunSync(Func<Task> task)
    {
        var oldContext = SynchronizationContext.Current;
        var syncContext = new ExclusiveSynchronizationContext();
        SynchronizationContext.SetSynchronizationContext(syncContext);

        syncContext.Post(async _ =>
        {
            try
            {
                await task();
            }
            catch (Exception e)
            {
                syncContext.InnerException = e;
                throw;
            }
            finally
            {
                syncContext.EndMessageLoop();
            }
        }, null);

        syncContext.BeginMessageLoop();

        SynchronizationContext.SetSynchronizationContext(oldContext);
    }

    /// <summary>
    /// 同步执行具有 T 返回类型的异步 Task<T> 方法。
    /// </summary>
    /// <typeparam name="T">返回类型</typeparam>
    /// <param name="task">要执行的 Task<T> 方法。</param>
    /// <returns>等待给定的 Task<T> 的结果。</returns>
    public static T RunSync<T>(Func<Task<T>> task)
    {
        var oldContext = SynchronizationContext.Current;
        var syncContext = new ExclusiveSynchronizationContext();
        SynchronizationContext.SetSynchronizationContext(syncContext);
        T result;

        syncContext.Post(async _ =>
        {
            try
            {
                result = await task();
            }
            catch (Exception e)
            {
                syncContext.InnerException = e;
                throw;
            }
            finally
            {
                syncContext.EndMessageLoop();
            }
        }, null);

        syncContext.BeginMessageLoop();

        SynchronizationContext.SetSynchronizationContext(oldContext);

        return result;
    }

    private class ExclusiveSynchronizationContext : SynchronizationContext
    {
        // ... 为简洁起见省略了实现细节
    }
}</code>
登入後複製

使用方法:

<code class="language-csharp">customerList = AsyncHelpers.RunSync(() => GetCustomers());</code>
登入後複製

此解決方法在需要同步運行異步方法的情況下效果很好。

以上是如何在C#中同步運行異步任務方法?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板