如何创建现有同步方法的异步重载?
How do I create an async overload of an existing synchronous method?
我有几个库目前不支持 async/await,我正在尝试更新它们。对于可以调用现有异步代码的方法(例如使用 File.ReadAllLinesAsync
而不是 File.ReadAllLines
),创建异步重载非常容易。但是,对于不调用其他具有异步能力的代码的方法,重载就不是那么容易了。
举个例子,假设我有一个方法如下:
public ResultType DoLotsOfStuff(string p1, string p2)
{
ResultType result = new ResultType();
// Do Lots of stuff here.
// update result
return result;
}
我想创建此方法的异步重载,但不想复制其中的所有代码。所以该方法简单地开始:
public Task<ResultType> DoLotsOfStuffAsync(string p1, string p2)
问题变成了我在新重载中如何调用原始方法?
我看到了几个可能的答案,但不确定其中是否有一个是好的,也不确定在什么情况下哪个是最好的。到目前为止,我已经看到了这些:
方法一:使用Task.Yield
public Task<ResultType> DoLotsOfStuffAsync(string p1, string p2)
{
Task.Yield();
return DoLotsOfStuff(p1, p2);
}
方法二:使用Task.Run
public Task<ResultType> DoLotsOfStuffAsync(string p1, string p2)
{
return await Task.Run(() => DoLotsOfStuff(p1, p2));
}
方法三:使用Task.FromResult
public Task<ResultType> DoLotsOfStuffAsync(string p1, string p2)
{
ResultType result = DoLotsOfStuff(p1, p2);
return await Task.FromResult(result);
}
这三个都编译得很好,所以我不确定该用哪个。它们等价吗?如果不是,分别使用的后果是什么?
作为背景知识,这些库可用于各种应用程序,包括 ASP.Net 核心网络应用程序、.Net Core 控制台应用程序和可能的 .Net Core UI 应用程序。我已经做了几个小时的互联网搜索并找到了所有这些方法,只是没有什么时候可以使用。
谢谢!
这三种方法都是伪异步。如果您不打算提供真正的异步实现(通过等待 naturally/actually 像 IO 这样的异步操作),那么根本不要提供这些重载。
我强烈推荐阅读 Task.Run Etiquette,Alexander Petrov 已经发表了评论。
我有几个库目前不支持 async/await,我正在尝试更新它们。对于可以调用现有异步代码的方法(例如使用 File.ReadAllLinesAsync
而不是 File.ReadAllLines
),创建异步重载非常容易。但是,对于不调用其他具有异步能力的代码的方法,重载就不是那么容易了。
举个例子,假设我有一个方法如下:
public ResultType DoLotsOfStuff(string p1, string p2)
{
ResultType result = new ResultType();
// Do Lots of stuff here.
// update result
return result;
}
我想创建此方法的异步重载,但不想复制其中的所有代码。所以该方法简单地开始:
public Task<ResultType> DoLotsOfStuffAsync(string p1, string p2)
问题变成了我在新重载中如何调用原始方法?
我看到了几个可能的答案,但不确定其中是否有一个是好的,也不确定在什么情况下哪个是最好的。到目前为止,我已经看到了这些:
方法一:使用Task.Yield
public Task<ResultType> DoLotsOfStuffAsync(string p1, string p2)
{
Task.Yield();
return DoLotsOfStuff(p1, p2);
}
方法二:使用Task.Run
public Task<ResultType> DoLotsOfStuffAsync(string p1, string p2)
{
return await Task.Run(() => DoLotsOfStuff(p1, p2));
}
方法三:使用Task.FromResult
public Task<ResultType> DoLotsOfStuffAsync(string p1, string p2)
{
ResultType result = DoLotsOfStuff(p1, p2);
return await Task.FromResult(result);
}
这三个都编译得很好,所以我不确定该用哪个。它们等价吗?如果不是,分别使用的后果是什么?
作为背景知识,这些库可用于各种应用程序,包括 ASP.Net 核心网络应用程序、.Net Core 控制台应用程序和可能的 .Net Core UI 应用程序。我已经做了几个小时的互联网搜索并找到了所有这些方法,只是没有什么时候可以使用。
谢谢!
这三种方法都是伪异步。如果您不打算提供真正的异步实现(通过等待 naturally/actually 像 IO 这样的异步操作),那么根本不要提供这些重载。
我强烈推荐阅读 Task.Run Etiquette,Alexander Petrov 已经发表了评论。