C# 当主线程卡在while循环(或Task.WaitAll)中时编辑GUI
因此,在长时间的诅咒和放弃希望之后,我几乎把一切都做好了 我有一个GUI,它显示连接地址列表和消息列表。通常,当我关闭连接器(断开与地址的连接)时,我会写一条消息:“断开与地址x的连接”。但是,正如您将从这些方法中看到的,在处理应用程序时,我不能使用dispatcher来编写该消息(C# 当主线程卡在while循环(或Task.WaitAll)中时编辑GUI,c#,dispose,dispatcher,C#,Dispose,Dispatcher,因此,在长时间的诅咒和放弃希望之后,我几乎把一切都做好了 我有一个GUI,它显示连接地址列表和消息列表。通常,当我关闭连接器(断开与地址的连接)时,我会写一条消息:“断开与地址x的连接”。但是,正如您将从这些方法中看到的,在处理应用程序时,我不能使用dispatcher来编写该消息(this.ModuleConnections.Remove(address);触发消息的编写,并从列表中直观地删除它) 我无法使用dispatcher,因为Task.WaitAll会停止线程。如果线程停止,调度程序将
this.ModuleConnections.Remove(address);
触发消息的编写,并从列表中直观地删除它)
我无法使用dispatcher,因为Task.WaitAll会停止线程。如果线程停止,调度程序将无法执行this.ModuleConnections.Remove(地址)如果tasks not finish task.WaitAll不会释放线程,则这将导致task not finish。这是一个非常大的问题
如果没有task.waitall,我会处理大量的对象和key not found异常以及其他让一些线程保持运行的讨厌的事情,因此应用程序不会完全关闭
但是现在,当它关闭时,GUI冻结(看起来像崩溃了)几秒钟,然后(当task.waitall完成时)关闭窗口,整个应用程序正确关闭
我想要的是仍然能够更新我的邮件列表并显示已断开连接的地址
只是澄清一下
我需要CloseConnector方法中的任务,因为关闭连接器(dispose)会使其断开连接,它需要等待从另一端收到消息后,代码才能继续。如果我一个接一个地运行这个程序,它将需要几分钟,就像我现在做的那样,它只需要几秒钟。我看到的第一件事是,如果您想使用WaitAll()
方法对所有任务进行tun,您不需要调用Start()
方法。另外,如果希望一次运行一个任务,最好使用task.run()
,它将Expression
作为参数。这种情况的不同之处在于,Run()
强制您的任务立即启动,而start()
不能保证您的任务现在就启动-只是计划从TaskScheduler
开始。顺便说一下,Wait()
的工作方式也是一样的
最后,检查您的此对象-此时这是什么?它不是空的吗?可能尝试使用闭包,并将您的调度程序作为参数
希望这有帮助没有任务。运行()。我在不处理时调用task.run for,因为这样就不需要等待任务完成。不知道task.waitall也会启动任务,可能会在task.start()周围放置if(mDisposed==false)。这个对象不是null,它永远不会是null,因为我总是实例化everyhting。你把Close和我的dispatcher当作arg是什么意思?这在你的情况下行吗<代码>应用程序支持.Dispatcher.Invoke(DispatcherPriority.Background,(disp)=>{disp.ModuleConnections.Remove(address);})代码>你不能那样做。但它仍然不能解决问题我可以问一下为什么这被否决了,我的问题表述错了吗?我不应该问这些问题吗?怎么了?为什么人们从不告诉你出了什么问题:(我不知道,但我确实认为提供一个服务会有所帮助。@PieterWitvoet谢谢pieter,我会在有更多时间时尝试添加它:)
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());
}
}