在主线程陷入while循环(或Task.WaitAll)时编辑GUI
本文关键字:WaitAll Task GUI 编辑 线程 循环 while | 更新日期: 2023-09-27 18:22:09
所以,经过长时间的咒骂和放弃希望,我(几乎)一切都好了。
我有一个GUI,它显示连接地址列表和消息列表。通常情况下,当我关闭连接器(断开与地址的连接)时,我会写一条消息说:"断开与x地址的连接"。然而,正如您将从这些方法中看到的那样,在处理应用程序时,我不能使用调度器来写入该消息(this.ModuleConnections.Remove(address);
触发消息的写入,并从列表中直观地删除它)。
private void CloseConnector(string address)
{
Task task = new Task(() =>
{
var moduleConnection = this.ModuleConnections[address];
moduleConnection.ModuleConnector.Dispose();
if (mDisposed == true)
{
ApplicationSupport.Dispatcher.Invoke(
DispatcherPriority.Background,
new Action(() =>
{
this.ModuleConnections.Remove(address);
}));
}
});
task.Start();
if (mDisposed == true)
{
mTasks.Add(task);
}
}
protected virtual void Dispose(bool disposing)
{
// Dispose managed resources.
if ((mDisposed == false) && (disposing == true))
{
mTasks.Clear();
mDisposed = true;
CloseConnectors();
Task.WaitAll(mTasks.ToArray());
}
}
我无法使用调度程序,因为Task.WaitAll会停止线程。如果线程停止,则调度程序无法执行this.ModuleConnections.Remove(address);
,这将导致任务未完成,如果任务未完成task.WaitAll将不会释放线程。这是一个很大的问题。
如果没有task.waitall,我将处理大量的对象和未找到密钥的异常以及其他令人讨厌的事情,这些事情使一些线程保持运行,因此应用程序不会完全关闭。
但现在,当它关闭时,GUI会冻结(看起来像崩溃了)几秒钟,然后(当task.waitall完成时)它会关闭窗口,整个应用程序也会正确关闭。
我想要的是仍然能够更新我的消息列表,并显示断开连接的地址。
只是为了澄清
我需要CloseConnector方法中的Task,因为关闭连接器(dispose)会使其断开连接,它需要等到收到来自另一端的消息后才能继续代码。如果我一个接一个地运行这个程序,它将需要几分钟,与我现在所做的并行,它只需要几秒钟。
我看到的第一件事是,如果您想用WaitAll()
minhod对它们进行调优,则不需要为任务调用Start()
方法。此外,如果您想一次运行一个任务,最好使用Task.Run()
,它将Expression
作为参数。这种情况下的区别在于,Run()
强制您的任务立即开始,而Start()
不能保证您的任务现在就开始——它只是计划从TaskScheduler
开始。顺便说一下,Wait()
的工作方式与相同
最后,检查您的this
对象——此时这是什么?它不是空的吗?也许可以尝试使用闭包并将您的dispatcher
作为arg
希望对有所帮助