我是多线程的新手,浪费了几天没有运气调试这个程序。我正在尝试做概念验证,然后再继续实施并进行生产。
我有一个自定义对象列表。它们的属性是Task类型的T和int类型的Timeout。我试图在parrallel中多次执行任务,如果超时则终止任务。出于演示目的,我确实创建了两个简单的任务,他们做了简单的事情
public class Program
{
public static void Main(string[] args)
{
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
CancellationToken cancellationToken = cancellationTokenSource.Token;
List<MyItem> myItems = new List<MyItem>();
myItems.Add(createtask1(2000,1000,cancellationToken)); // this task should run for one second....result: should timeout
myItems.Add(createtask2(2000,3000,cancellationToken));// this task should run for two second....result: should NOT timeout
Parallel.ForEach(myItems,(item)=>{
Task task = item.T;
// start the task
task.Start();
Console.WriteLine("waiting for the task with timeout:{0} to finish", item.Timeout);
try{
bool hasNotTimedOut = task.Wait(item.Timeout);
if (hasNotTimedOut)
{
Console.WriteLine("Task with timeout: {0}, has not timed out", item.Timeout);
}
else
{
Console.WriteLine("Task with timeout: {0}, has timed out", item.Timeout);
cancellationTokenSource.Cancel();
Console.WriteLine("Status of the task with timeout: {0} is {1}", item.Timeout,task.Status.ToString());
}
}
catch (AggregateException ex)
{
if (ex.InnerException is OperationCanceledException)
{
Console.WriteLine("Status of the task with timeout: {0} is {1}5", item.Timeout,task.Status.ToString());
}
else
Console.WriteLine(ex);
}
});
// Task.WaitAll(myItems.Select(item=>item.T).ToArray());
Console.WriteLine("End of Main");
}
private static MyItem createtask1(int delayTime, int timeout,CancellationToken cancellationToken)
{
MyItem toReturn = new MyItem();
toReturn.Timeout = timeout;
toReturn.T = new Task(()=>{
Console.WriteLine("Task1 is getting executed with DelayTime:{0}, timeout:{1}",delayTime,timeout);
Task.Delay(delayTime).Wait();
Console.WriteLine("Task1 finished executing with DelayTime:{0}, timeout:{1}",delayTime,timeout);
cancellationToken.ThrowIfCancellationRequested();
},cancellationToken);
return toReturn;
}
private static MyItem createtask2(int delayTime, int timeout,CancellationToken cancellationToken)
{
MyItem toReturn = new MyItem();
toReturn.Timeout = timeout;
toReturn.T = new Task(()=>{
Console.WriteLine("Task2 is getting executed with DelayTime:{0}, timeout:{1}",delayTime,timeout);
Task.Delay(delayTime).Wait();
Console.WriteLine("Task2 finished executing with DelayTime:{0}, timeout:{1}",delayTime,timeout);
cancellationToken.ThrowIfCancellationRequested();
},cancellationToken);
return toReturn;
}
}
public class MyItem{
public Task T{get;set;}
public int Timeout{get;set;}
}
似乎它正在尝试取消上一个任务,但在我的情况下,第一个案例应该被取消。如果我不包含CancellationToken,我的代码可以正常工作,即它告诉我什么任务超时。
你能告诉我我做错了吗