c# – 将异步操作转换为异步函数委托,保留同步异常传递
发布时间:2020-12-15 23:31:16 所属栏目:百科 来源:网络整理
导读:我想将异步操作委托转换为返回指定值的异步函数委托.我想出了一个扩展方法: public static FuncTaskTResult ReturnTResult(this FuncTask asyncAction,TResult result){ ArgumentValidate.NotNull(asyncAction,nameof(asyncAction)); return async () = { a
我想将异步操作委托转换为返回指定值的异步函数委托.我想出了一个扩展方法:
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 有没有办法以同步异常继续同步传递的方式创建此包装器?继续继续前进的道路吗? 更新:同步抛出异常的异步操作的具体示例: 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,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 解决方法
好吧,你将无法在初始调用中使用异步.这很清楚.但是您可以使用调用该函数的同步委托,然后捕获返回的任务以在异步委托中等待它:
public static Func<Task<TResult>> Return<TResult>(this Func<Task> asyncAction,nameof(asyncAction)); return () => { // Call this synchronously var task = asyncAction(); // Now create an async delegate for the rest Func<Task<TResult>> intermediate = async () => { await task; return result; }; return intermediate(); }; } 或者,将它重构为两个方法,基本上将异步lambda表达式提取为异步方法: public static Func<Task<TResult>> Return<TResult>( this Func<Task> asyncAction,nameof(asyncAction)); return () => { var task = asyncAction(); return AwaitAndReturn(task,result); }; } public static async Func<Task<TResult>> AwaitAndReturn<TResult>( this Task asyncAction,TResult result) { await task; return result; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |