Task.Start 奇怪的行为
Task.Start strange behavior
您好,我有以下创建任务的代码。然后设置它开始。
该任务旨在向 ConcurrentBag
列表添加响应。
但是await似乎并不是在等待所有任务完成。但是它们被标记为已完成。列表中只有一项任务。
使用 Task.Run
!
时效果很好
public async void RunT1()
{
DoesNotWork();
}
public async void RunT2()
{
DoesWork();
}
public async void DoesNotWork()
{
ConcurrentBag<string> concurrentBag = new ConcurrentBag<string>();
List<Task> taskList = new List<Task>();
Task task1 = new Task(async () =>
{
var xml = await LongWorkingMethod();
concurrentBag.Add(xml);
});
taskList.Add(task1);
taskList[0].Start();
await Task.WhenAll(taskList);
if (concurrentBag.Count > 0) //concurrentBag is empty,
//even though the task has finished
{
Debug.Print("success");
}
}
public async void DoesWork()
{
ConcurrentBag<string> concurrentBag = new ConcurrentBag<string>();
List<Task> taskList = new List<Task>();
Task task1 = Task.Run(async () =>
{
var xml = await LongWorkingMethod();
concurrentBag.Add(xml);
});
taskList.Add(task1);
await Task.WhenAll(taskList);
if (concurrentBag.Count > 0) //concurrentBag is NOT empty
{
Debug.Print("success");
}
}
几乎没有理由直接使用 Task
构造函数。
在你的情况下,Task
构造函数不支持 async
委托(即 Action
而不是 Func<Task>
),当你将一个作为参数传递时它被视为 async void
.
这意味着调用Start
"fires and forgets"这个委托,它不能等待里面的异步操作完成,因为没有Task
到 await
上。
var task = new Task(async () => await Task.Delay(1000));
task.Start();
await task; // completes immediately
在需要 运行 新 Task
的情况下使用 Task.Run
。如您所见,Task.Run
确实支持 async
委托并等待整个操作完成
var task = Task.Run(async () => await Task.Delay(1000));
await task; // completes after 1000 milliseconds
您好,我有以下创建任务的代码。然后设置它开始。
该任务旨在向 ConcurrentBag
列表添加响应。
但是await似乎并不是在等待所有任务完成。但是它们被标记为已完成。列表中只有一项任务。
使用 Task.Run
!
public async void RunT1()
{
DoesNotWork();
}
public async void RunT2()
{
DoesWork();
}
public async void DoesNotWork()
{
ConcurrentBag<string> concurrentBag = new ConcurrentBag<string>();
List<Task> taskList = new List<Task>();
Task task1 = new Task(async () =>
{
var xml = await LongWorkingMethod();
concurrentBag.Add(xml);
});
taskList.Add(task1);
taskList[0].Start();
await Task.WhenAll(taskList);
if (concurrentBag.Count > 0) //concurrentBag is empty,
//even though the task has finished
{
Debug.Print("success");
}
}
public async void DoesWork()
{
ConcurrentBag<string> concurrentBag = new ConcurrentBag<string>();
List<Task> taskList = new List<Task>();
Task task1 = Task.Run(async () =>
{
var xml = await LongWorkingMethod();
concurrentBag.Add(xml);
});
taskList.Add(task1);
await Task.WhenAll(taskList);
if (concurrentBag.Count > 0) //concurrentBag is NOT empty
{
Debug.Print("success");
}
}
几乎没有理由直接使用 Task
构造函数。
在你的情况下,Task
构造函数不支持 async
委托(即 Action
而不是 Func<Task>
),当你将一个作为参数传递时它被视为 async void
.
这意味着调用Start
"fires and forgets"这个委托,它不能等待里面的异步操作完成,因为没有Task
到 await
上。
var task = new Task(async () => await Task.Delay(1000));
task.Start();
await task; // completes immediately
在需要 运行 新 Task
的情况下使用 Task.Run
。如您所见,Task.Run
确实支持 async
委托并等待整个操作完成
var task = Task.Run(async () => await Task.Delay(1000));
await task; // completes after 1000 milliseconds