gpt4 book ai didi

c# - 将同步代码包装为异步任务的最佳方式是什么?

转载 作者:行者123 更新时间:2023-11-30 16:54:05 25 4
gpt4 key购买 nike

我正在实现一个异步的接口(interface)方法(返回任务)。但是,我的实现必然是同步的。最好的方法是什么?有一些内置的方法可以做到这一点吗?以下是我正在考虑的几个选项:

  • 选项 1:Task.FromResult

    return Task.FromResult(ComputeResult());

这很好,因为我的代码是同步运行的。缺点是如果 ComputeResult() 失败或被取消,我的方法将抛出异常而不是返回失败的任务。

  • 选项 2:Task.Run

    return Task.Run(() => ComputeResult());

这会更自然地传播失败和取消。但是,这也引入了不必要的线程跳跃。

  • 选项 3:TaskCompletionSource

    var tcs = new TaskCompletionSource<T>();
    try
    {
    tcs.SetResult(ComputeResult());
    }
    catch (OperationCanceledException)
    {
    tcs.SetCanceled();
    }
    catch (Exception ex)
    {
    tcs.SetException(ex);
    }

    return tcs.Task;

这既传播了失败/取消又避免了线程跳转,但它更加冗长和复杂。

最佳答案

您可能忽略了另外两个选项:

  • 只需让您的方法async 并执行return ComputeResult()。使用 pragma 抑制编译器警告。如果你不想抑制警告,你可以这样做:

    async Task<Result> ComputeResultAsync()
    {
    await Task.FromResult(0);
    return ComputeResult();
    }
  • 使用Task.RunSynchronously:

    Task<Result> ComputeResultAsync()
    {
    var task = new Task<Result>(() => ComputeResult());
    task.RunSynchronously(TaskScheduler.Default);
    return task;
    }

后者将提供类似于async 方法的异常传播。但是请注意,under certain conditions (比如当它在堆栈中太深时),RunSynchronously 仍然可以异步执行。

关于c# - 将同步代码包装为异步任务的最佳方式是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30851940/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com