C# 当主线程卡在while循环(或Task.WaitAll)中时编辑GUI

C# 当主线程卡在while循环(或Task.WaitAll)中时编辑GUI,c#,dispose,dispatcher,C#,Dispose,Dispatcher,因此,在长时间的诅咒和放弃希望之后,我几乎把一切都做好了 我有一个GUI,它显示连接地址列表和消息列表。通常,当我关闭连接器(断开与地址的连接)时,我会写一条消息:“断开与地址x的连接”。但是,正如您将从这些方法中看到的,在处理应用程序时,我不能使用dispatcher来编写该消息(this.ModuleConnections.Remove(address);触发消息的编写,并从列表中直观地删除它) 我无法使用dispatcher,因为Task.WaitAll会停止线程。如果线程停止,调度程序将

因此,在长时间的诅咒和放弃希望之后,我几乎把一切都做好了

我有一个GUI,它显示连接地址列表和消息列表。通常,当我关闭连接器(断开与地址的连接)时,我会写一条消息:“断开与地址x的连接”。但是,正如您将从这些方法中看到的,在处理应用程序时,我不能使用dispatcher来编写该消息(
this.ModuleConnections.Remove(address);
触发消息的编写,并从列表中直观地删除它)

我无法使用dispatcher,因为Task.WaitAll会停止线程。如果线程停止,调度程序将无法执行
this.ModuleConnections.Remove(地址)
如果没有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());
    }
}