一、从异步方法的声明说起
无返回值的类型异步方法
(1)public async Task MethodName()
带返回值类型的异步方法
(2)public async Task<TResult> MethodName()
注意有无返回值只是相对于同步方法来说的,其实直接执行异步方法(不与await结合使用)是有返回值的,分别返回 Task、Task<TResult>
要注意的是 异步 lambda表达式 与 异步方法 一样,使用 Func委托 直接调用也有相应的返回值 Task 或 Task<TResult>,自然也可以 结合 await 使用
无返回值的类型异步方法对应的 lambda
(1)async () => {}
对应于Func委托:Func<Task>
带返回值类型的异步方法对应的 lambda
(2)async () => { return TResult; }
对应于Func委托:Func<Task<TResult>>
接下来简单演示一下上述问题
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApp1 { class TaskSummary { public static async void RunTaskSummary() { AsyncMethodDemo(); AsyncLambdaDemo(); } public static async void AsyncLambdaDemo() { Func<Task> asyncLambda = async () => { Console.WriteLine("[AsyncLambda] Hello, Lambda"); }; Task task = asyncLambda(); Console.WriteLine($"[AsyncLambdaDemo] AsyncLambda()返回值为 {task}"); Func<Task<string>> asyncParamLambda = async () => { Console.WriteLine("[AsyncParamLambda] Hello, Param Lambda"); return "AsyncParamLambda Return Value"; }; Task<string> task2 = asyncParamLambda(); Console.WriteLine($"[AsyncLambdaDemo] AsyncParamLambda()返回值为 {task2}"); Console.WriteLine($"[AsyncLambdaDemo] AsyncParamLambda()返回值参数为 {task2.Result}"); } public static async Task AsyncMethodDemo() { Task task = AsyncMethod(); Console.WriteLine($"[AsyncMethodDemo] AsyncMethod()返回值为 {task}"); Task<string> task2 = AsyncParamMethod(); Console.WriteLine($"[AsyncMethodDemo] AsyncParamMethod()返回值为 {task2}"); Console.WriteLine($"[AsyncMethodDemo] AsyncParamMethod()返回值参数为 {task2.Result}"); } private static async Task<string> AsyncParamMethod() { Console.WriteLine("[AsyncMethod] Hello, Param AsyncMethod"); return "AsyncParamMethod Return Value"; } public static async Task AsyncMethod() { Console.WriteLine("[AsyncMethod] Hello, AsyncMethod"); } } }
[AsyncMethod] Hello, AsyncMethod [AsyncMethodDemo] AsyncMethod()返回值为 System.Threading.Tasks.Task`1[System.Threading.Tasks.VoidTaskResult] [AsyncMethod] Hello, Param AsyncMethod [AsyncMethodDemo] AsyncParamMethod()返回值为 System.Threading.Tasks.Task`1[System.String] [AsyncMethodDemo] AsyncParamMethod()返回值参数为 AsyncParamMethod Return Value [AsyncLambda] Hello, Lambda [AsyncLambdaDemo] AsyncLambda()返回值为 System.Threading.Tasks.Task`1[System.Threading.Tasks.VoidTaskResult] [AsyncParamLambda] Hello, Param Lambda [AsyncLambdaDemo] AsyncParamLambda()返回值为 System.Threading.Tasks.Task`1[System.String] [AsyncLambdaDemo] AsyncParamLambda()返回值参数为 AsyncParamLambda Return Value
二、Task.Run()
Task.Run()
参数可以为:(1)Action委托表示无参无返回值的方法
同步方法:public void MethodName()Lambda: () => {}
(2)Func<Task>委托
表示无参无返回值的方法
异步方法:public async Task MethodName()Lambda: async () => {}
此处注意一种用法
符合Func<Task>委托
Task task2 = Task.Run(() => ParamteredAsyncFunc("param"));
public async Task ParamteredAsyncFunc(string param)
Task.Run<TResult>()带返回值版本的Run()
参数可以为:(1)Func<TResult>
表示无参且具有一个 TResult类型 返回值的方法
应该是表示同步方法同步方法:public TResult MethodName()
Lambda: ()=>TResult
(2)Func<Task<TResult>>
表示无参且具有一个 Task<TResult>类型 返回值的方法
应该用于异步方法异步方法:public async Task<TResult> MethodName()
Lambda: async()=> TResult
示例如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApp1 { class TaskRunSummary { public static async void RunTaskSummary() { //Task.Run() Action Lambda Task t1 = Task.Run(() => { Console.WriteLine("Task.Run() Action Lambda"); }); await t1; //Task.Run() Func<Task> Lambda Async Task t2 = Task.Run(async () => { Console.WriteLine("Task.Run() Func<Task> Lambda Async"); }); await t2; //Task.Run() Func<Task> Method Async Task t3 = Task.Run(MethodAsync); await t3; //Task.Run<TResult>() Func<TResult> Lambda Task<string> t4 = Task.Run<string>(() => { Console.WriteLine("Task.Run<TResult>() Func<TResult> Lambda"); return "Task.Run<TResult>() Func<TResult> Lambda Return Value"; }); Console.WriteLine(await t4); //Task.Run<TResult>() Func<Task<TResult>> Lambda Async Task<string> t5 = Task.Run<string>(async () => { Console.WriteLine("Task.Run<TResult>() Func<Task<TResult>> Lambda Async"); return "Task.Run<TResult>() Func<Task<TResult>> Lambda Async Return Value"; }); Console.WriteLine(await t5); //Task.Run<TResult>() Func<Task<TResult>> Method Async Task<string> t6 = Task.Run<string>(new Func<Task<string>>(ParameteredMethodAsync)); Console.WriteLine(await t6); } public static async Task MethodAsync() { Console.WriteLine("Task.Run() Func<Task> Method Async"); } public static async Task<string> ParameteredMethodAsync() { Console.WriteLine("Task.Run<TResult>() Func<Task<TResult>> Method Async"); return "Task.Run<TResult>() Func<Task<TResult>> Method Async Return Value"; } } }
三、注意一点
Task<TResult>.Start()会异步执行,而对TResult的引用会阻塞直到Task执行完毕