C#4.0的并行库TPL,即Task(一)http://47.98.154.65/?id=1793
C#4.0的并行库TPL,即Task(二) http://47.98.154.65/?id=1798
C#4.0的并行库TPL,即Task(三) http://47.98.154.65/?id=1808
C#4.0的并行库TPL,即Task(四) http://47.98.154.65/?id=1815
C#4.0的并行库TPL,即Task(五) http://47.98.154.65/?id=1816
这一节再继续谈谈
Task WhenAll、WhenAny
先上代码:
代码是那本C#多线程编程书里的。
static int TaskMethod(string name, int seconds)
{
Console.WriteLine("Task {0} 运行在线程 {1} 上。是否是线程池线程: {2}",
name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
Thread.Sleep(TimeSpan.FromSeconds(seconds));
return 42 * seconds;
}WhenAll:
这里设置了一个名字为whenAllTask的变量,他是用静态方法Task.WhenAll创建的第三个任务。需要注意的是,由于是基于前面两个任务创建的,因此返回的类型为 Task<int[]>。在firstTask和secondTask运行完毕后(WhenAll), 采用后续操作(ContinueWith),函数中的t其实也就是whenAllTask的传参。后续操作打印出whenAllTask中的Result数组成员,后续操作的状态条件为 whenAllTask的状态为OnlyOnRanToCompletion。
var firstTask = new Task<int>(() => TaskMethod("First Task", 3));
var secondTask = new Task<int>(() => TaskMethod("Second Task", 2));
var whenAllTask = Task.WhenAll(firstTask, secondTask);
whenAllTask.ContinueWith(t =>Console.WriteLine("The first answer is {0}, the second is {1}", t.Result[0], t.Result[1]),
TaskContinuationOptions.OnlyOnRanToCompletion
);
firstTask.Start();
secondTask.Start();WhenAny:
首先建立一个Task List,名字为tasks。而后依次向里添加新任务实例,而且新任务的运行所需时间依次为1、2、3秒。而后,伦查tasks中的任务数量,在循环内 建立completedTask任务,用来表示任一个在tasks中已经完成操作的Task,如果一个任务都没运行完成,则completedTask。
需要指出的是, 这里的Result和上例中的不同,上例中t.Result直接指代int[],即返回结果数组;而这里的WhenAny(tasks).Result指的是Task<int>,也就是完成的Task<int>实例。
var tasks = new List<Task<int>>();
for (int i = 1; i < 4; i++)
{
int counter = i;
var task = new Task<int>(() => TaskMethod(string.Format("Task {0}", counter), counter));
tasks.Add(task);
task.Start();
}
while (tasks.Count > 0)
{
var completedTask = Task.WhenAny(tasks).Result;//这里的Result是指代Task<int>!
tasks.Remove(completedTask);
Console.WriteLine("A task has been completed with result {0}.", completedTask.Result);
}这里勇哥想补充的是,你可能在即时窗口中发现completedTask是有Result属性的。
但实际上completedTask.Result可能提示非法属性。

问题代码如下:
while (TaskCount() > 0)
{
var completedTask = Task.WhenAny(TaskList).Result;
if (completedTask.Result==-1)
{
SetIsCanceled();
CMessage.Instance.AddTipsMessage(CMessage.DeviceMessageTypeEnum.WorkMsg, $"Task[{completedTask.Id}]: Task被用户取消!");
}
}其实原因是:
TaskList的定义少了返回类型。
原来是: public readonly List<Task> TaskList = new List<Task>(); 解决办法是: public readonly List<Task<int>> TaskList = new List<Task<int>>(); 这个时候你会发现completedTask.Result就可用了。 这是因为WhenAny(tasks).Result指的是Task,但是你之前的Task是不带参数的,所以没有云Result


少有人走的路

















