【发布时间】:2023-03-13 00:07:02
【问题描述】:
我想将异步操作委托转换为返回指定值的异步函数委托。我为此想出了一个扩展方法:
public static Func<Task<TResult>> Return<TResult>(this Func<Task> asyncAction, TResult result)
{
ArgumentValidate.NotNull(asyncAction, nameof(asyncAction));
return async () =>
{
await asyncAction();
return result;
};
}
但是,我的扩展方法有问题,因为本来可以从操作委托同步传递的异常现在从函数委托异步传递。具体来说:
Func<Task> asyncAction = () => { throw new InvalidOperationException(); };
var asyncFunc = asyncAction.Return(42);
var task = asyncFunc(); // exception should be thrown here
await task; // but instead gets thrown here
有没有办法以同步异常继续同步传递的方式创建这个包装器? ContinueWith 是要走的路吗?
更新:同步抛出异常的异步操作的具体示例:
public static Task WriteAllBytesAsync(string filePath, byte[] bytes)
{
if (filePath == null)
throw new ArgumentNullException(filePath, nameof(filePath));
if (bytes == null)
throw new ArgumentNullException(filePath, nameof(bytes));
return WriteAllBytesAsyncInner(filePath, bytes);
}
private static async Task WriteAllBytesAsyncInner(string filePath, byte[] bytes)
{
using (var fileStream = File.OpenWrite(filePath))
await fileStream.WriteAsync(bytes, 0, bytes.Length);
}
测试:
Func<Task> asyncAction = () => WriteAllBytesAsync(null, null);
var asyncFunc = asyncAction.Return(42);
var task = asyncFunc(); // ArgumentNullException should be thrown here
await task; // but instead gets thrown here
【问题讨论】:
-
你能提供一个更具体的例子吗?
-
不清楚为什么您希望同步抛出异常。如果你调用
asyncAction()那也不会抛出异常——它会返回一个错误的任务。 -
@JonSkeet:你是对的;我的示例中有一个小错误(匿名函数不应该被标记为
async)。这个问题现在有意义吗? -
@Douglas:嗯。只是因为你的
Func<Task>实际上并没有做 anything 异步。大概通常它是实际使用 async/await 的代码,只是碰巧抛出了异常?到那时,你会再次调用asyncAction()而不是抛出。 -
@DanielA.White:有关使用此功能的具体示例,请查看my answer here 的最后一个代码 sn-p(在“更新”下)中的第三个重载。
标签: c# .net asynchronous async-await task