Task<T>
方法?在异步编程中,方法通常定义为异步任务 (Task<T>
) 以提高应用程序的性能和响应能力。但是,在某些情况下,您可能需要同步执行异步方法,以进行调试或测试。
一种方法是使用 Task.Wait()
方法,该方法会阻塞调用线程,直到任务完成。但是,在某些情况下,这会导致 UI 冻结和性能问题。
另一种选择是使用 Task.RunSynchronously()
方法。虽然听起来它会同步运行任务,但如果任务没有绑定到委托,它实际上会抛出异常。
最后,您可以使用涉及调度程序帧的解决方法。创建一个新的 DispatcherFrame
,启动它,并在 lambda 表达式中等待任务。任务完成后,将调度程序帧的 Continue
属性设置为 false
以停止调度程序泵。
一个更强大的解决方案是使用同步上下文,该上下文会泵送消息,直到任务完成。这是一个实现此解决方法的类:
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 { // ... 为简洁起见省略了实现细节 } }
使用方法:
customerList = AsyncHelpers.RunSync(() => GetCustomers());
此解决方法在需要同步运行异步方法的情况下效果很好。
以上是如何在C#中同步运行异步任务方法?的详细内容。更多信息请关注PHP中文网其他相关文章!