首页 > 后端开发 > C++ > 如何在C#中同步运行异步任务方法?

如何在C#中同步运行异步任务方法?

DDD
发布: 2025-02-01 07:16:08
原创
932 人浏览过

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

如何在 C# 中同步运行异步 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中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板