man*_*nok 3 c# overloading task multitasking async-await
public static T SyncVer<T>(Func<T> callback)
{
using (new LogContext("new logging context"))
{
try
{
return callback();
}
catch (Exception ex)
{
Console.WriteLine(ex);
throw;
}
}
}
public static async Task<T> AsyncVer<T>(Func<Task<T>> callback)
{
using (new LogContext("new logging context"))
{
try
{
return await callback();
}
catch (Exception ex)
{
Console.WriteLine(ex);
throw;
}
}
}
Run Code Online (Sandbox Code Playgroud)
请考虑上面的代码。您可能会看到两个函数中的大部分代码是相同的。我正在寻找一种方法,通过将它们重载为一个来将它们分组,这样我就不需要复制内容。有没有办法去掉两个函数中相似的部分?
提供的任何帮助将不胜感激。提前致谢。
注意Task.FromResult
会分配,并且GetAwaiter().GetResult()
可能死锁
就我个人而言,我只会创建两个方法而不用担心它。
\n然而,另一种(稍微更安全)的方法是将回调包装在ValueTask
. ValueTasks
如果它们同步执行,效果最好,但是它们有一些微妙的限制,并且永远不应等待多次。
假设是,这都是关于创建可等待和不可等待的委托重载、代码重用,并且等待此调用的同步版本对您来说不是问题。
\n给定
\npublic static async ValueTask<T> SomethingAsync<T>(Func<T> callback)\n => await SomethingAsync(() => new ValueTask<T>(callback()));\n\npublic static async ValueTask<T> SomethingAsync<T>(Func<Task<T>> callback)\n => await SomethingAsync(() => new ValueTask<T>(callback()));\n\npublic static async ValueTask<T> SomethingAsync<T>(Func<ValueTask<T>> callback)\n{\n using (new LogContext("new logging context"))\n {\n try\n {\n return await callback();\n }\n catch (Exception ex)\n {\n Console.WriteLine(ex);\n throw;\n }\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\n用法
\npublic static string DoSomething()\n{\n Console.WriteLine("execute sync");\n return "sync result";\n}\n\npublic static async Task<string> DoSomethingAsync()\n{\n Console.WriteLine("Execute async");\n await Task.Delay(100);\n return "async result";\n}\n\n\n...\n\nConsole.WriteLine(await SomethingAsync(DoSomething));\nConsole.WriteLine(await SomethingAsync(DoSomethingAsync));\n
Run Code Online (Sandbox Code Playgroud)\n输出
\nCreate\nexecute sync\nDispose\nsync result\nCreate\nExecute async\nDispose\nasync result\n
Run Code Online (Sandbox Code Playgroud)\n要提高效率,您可以省略包装器
\n示例
\npublic static ValueTask<T> SomethingAsync<T>(Func<T> callback)\n{\n try\n {\n return SomethingAsync(() => new ValueTask<T>(callback()));\n }\n catch (Exception e)\n {\n return ValueTask.FromException<T>(e);\n }\n}\n\npublic static ValueTask<T> SomethingAsync<T>(Func<Task<T>> callback)\n{\n try\n {\n return SomethingAsync(() => new ValueTask<T>(callback()));\n }\n catch (Exception e)\n {\n return ValueTask.FromException<T>(e);\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\n 注意:ValueTask.FromException
仅适用于.NET 5.0+
这种方法的好处:
\n缺点是
\n注意:我个人从来不需要这样做,我只会创建这两个方法\xc2\xaf\\_(\xe3\x83\x84)_/\xc2\xaf
。
其他资源
\n\n