天天看点

【C#】44. Task<T> 根据带返回值的函数构造Task

上篇中,我们看了不带参数值和返回值的函数(Action)构造Task的方法,本篇中我们想Thread一样,看看如何给Task传参和返回值。

首先定义int TaskMethod(String)函数,该函数以String作为参数,返回Int类型结果:

static int TaskMethod(string name)
{
Console.WriteLine("Task {0} 运行在线程id为{1}的线程上。是否是线程池中线程?:{2}",
name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
Thread.Sleep(2000);
return 42;
}
           
static Task<int> CreateTask(string name)
{
return new Task<int>(() => TaskMethod(name));
}
           

一、最简单的构造Task的方式为使用lambda表达式:

Task<int> task = new Task<int>(() => TaskMethod("Task 1"));
task.Start();
int result = task.Result;
Console.WriteLine("Result is: {0}", result);
           

需要注意的是,我们构造了Task<int>任务,然后Start(),之后返回值即task. Result属性!由于Result的关系, 因此线程将等待result得到后再往下进行。

【C#】44. Task&lt;T&gt; 根据带返回值的函数构造Task

二、Task同步运行RunSynchronously

Task<int>  task = CreateTask("Task 2");
task.RunSynchronously(); //运行在主线程中,等同于直接运行: TaskMethod("Task 2");
int result = task.Result;
Console.WriteLine("Result is: {0}", result);
           

这里没有使用Start()而是使用 RunSynchronously(),直接同步运行!等同于直接运行 Result =  TaskMethod("Task 2");

因此,该Task不是运行在线程池中,而是运行在主线程中。

【C#】44. Task&lt;T&gt; 根据带返回值的函数构造Task

三、Task的运行状态

Task<int> task = CreateTask("Task 3");
Console.WriteLine(task.Status);
task.Start();
while (!task.IsCompleted)
{
Console.WriteLine(task.Status);
Thread.Sleep(TimeSpan.FromSeconds(0.5));
}
Console.WriteLine(task.Status);
int result = task.Result;
Console.WriteLine("Result is: {0}", result);
           

上面的代码使用了状态判断(IsCompleted)轮查方式,输出了不同的Task状态。等到task执行完毕后,也就自然得到int结果。

【C#】44. Task&lt;T&gt; 根据带返回值的函数构造Task