结果现在显示在 UI 中,直到所有任务都完成,即使我在单个任务完成时在 UI 中添加
本文关键字:任务 UI 添加 单个 完成时 显示 结果 | 更新日期: 2023-09-27 18:36:04
在我的WPF应用程序中,我正在使用任务在单独的线程中进行一些后台处理。之后,当我开始从这些任务中获取结果时,我将结果更新到列表框中。除了每个任务完成时结果不会写入列表框之外,一切都运行良好。一旦我的任务数组中的所有项目都完成后,所有结果都会写入列表框,因此用户基本上无法看到我们收到这些结果的结果。相反,他们必须等到最后一个任务完成,然后才能在该列表框中显示任何内容。下面是我遇到问题的相关代码的一小部分。整个事情太大了,有很多不相关的东西不能在这里展示。我在代码中做错了什么导致这种延迟吗?
Task<String>[] myTasks = myListWithData.AsParallel().WithDegreeOfParallelism(10).Select( x => RunSomeMethod(x)).ToArray();
// Here I am back at the UI thread
while ( myTasks.Length > 0 )
{
try
{
int i = Task.WaitAny(myTasks);
string Result = myTasks[i].Result;
this.lst1.Items.Add(Result); // result is been added in the listbox. It should be available now??
// here is my logic for removing task with index i from myTasks
}
catch (Exception ex)
{
}
}
// At this point, user gets to see results for all tasks in that listbox
编辑
更新代码,其中包含有关如何创建任务数组的更多详细信息
假设此方法在 UI 线程上运行,则存在许多问题:
-
此方法阻止。 在此方法完成之前,UI 不会更新,这将在所有任务完成后更新。
-
Parallel
/PLINQ
将使用调用线程作为并行处理线程之一,因此这也将阻塞。 -
目前尚不清楚
RunSomeMethod
做什么,但是当它返回Task<string>
时,这意味着它返回而不完成并且异步完成。 如果它在返回任务之前实际上没有做任何工作,那么我看不到MaxDegreeOfParallelism(10)
实际上在做任何事情:所有任务都将几乎立即创建(并在创建时阻止)。
假设为 .NET 4.5,这将解决大多数问题。 如果需要调用方法(对于其他代码),Task.WhenAll
则需要将调用方法标记为async
:
var tasks = myListWithData.Select(ProcessAsync).ToArray();
await Task.WhenAll(tasks);
// continue
ProcessAsync
定义如下,假设RunSomeMethod
在ThreadPool
线程上执行:
private async Task ProcessAsync(string data)
{
var result = await RunSomeMethod(data);
lst1.Items.Add(result);
}
如果你使用的是 .NET 4.0,则可以使用延续。无需在 UI 线程中等待 while
循环获取结果,因为Task.WaitAny
会阻塞线程。
.NET 4.0
for(var i=0; i < taskCount; ++i)
{
Task.Factory.StartNew(() => // some long running stuff which returns string)
.ContinueWith(t => this.lst1.Items.Add(t.Result),
TaskScheduler.FromCurrentSynchronizationContext());
}
对于 .Net 4.5 或更高版本,您可以按照建议@SLaks使用await
。