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中文網其他相關文章!