Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 即使使用多线程,UI仍然锁定_C#_Wpf_Multithreading_Dispatcher - Fatal编程技术网

C# 即使使用多线程,UI仍然锁定

C# 即使使用多线程,UI仍然锁定,c#,wpf,multithreading,dispatcher,C#,Wpf,Multithreading,Dispatcher,我正在做一个项目,在UI方面遇到了很多障碍。 在本例中,创建一个新线程来更新UI,以便UI主线程保持打开状态,允许您仍然使用UI 我不确定这有什么问题。我想我可能是在使用dispatcher来创建线程,而不是创建一个使用主线程的线程??另外值得注意的是,我的main窗口是单例实例 private void button_Click(object sender, RoutedEventArgs e) { if (go) { city = textBox.Ge

我正在做一个项目,在UI方面遇到了很多障碍。 在本例中,创建一个新线程来更新UI,以便UI主线程保持打开状态,允许您仍然使用UI

我不确定这有什么问题。我想我可能是在使用dispatcher来创建线程,而不是创建一个使用主线程的线程??另外值得注意的是,我的
main窗口是单例实例

private void button_Click(object sender, RoutedEventArgs e)
{    
    if (go)
    {
        city = textBox.GetLineText(0);
        if (city == "exit")
        {
            Environment.Exit(0);
        }

        Thread t1 = new Thread(new ThreadStart(
                    delegate
                    {
                       this.Dispatcher.Invoke(DispatcherPriority.Background, new Action(start));
                    }));
         t1.Start();
         //await Task.Run(() => start());
    }
}

您不需要创建新线程。当您使用async和Wait时,将从线程池自动分配一个新线程。只需使您的按钮\u单击事件处理程序,如下面代码中所述,并使用
wait
关键字调用长时间运行的任务

private async void button_Click(object sender, RoutedEventArgs e)
{
    if (go)
    {
        city = textBox.GetLineText(0);
        if (city == "exit")
        {
            Environment.Exit(0);
        }

        await Task.Run(() => start());
    }
}
这里将发生的是当您单击按钮时,事件将被处理。如果满足条件,则在此行中启动长时间运行的任务
wait task.Run(()=>start())。然后它将返回到UI线程而不阻塞它,即当另一个线程在后台执行长时间运行的进程时,UI仍将响应

请阅读

编辑: 由于要控制
start()
方法中的UI元素,请使用以下方法:

private async void button_Click(object sender, RoutedEventArgs e)
{
    if (go)
    {
        city = textBox.GetLineText(0);
        if (city == "exit")
        {
            Environment.Exit(0);
        }

        await start();
    }
}

private async Task start()
{
    await Task.Run(async () => 
    {
       // long running task here
    });   

    // UI Control code here.
}

为什么启动一个新线程只是为了立即调用调度程序?dispatcher.invoke()在调用到的线程中执行操作,从而同时阻塞该线程和从中调用的线程。节约使用!只有在触摸UI时才需要它,并且不需要设置引发PropertyChanged的属性,即使UI响应它们。您的
start()
方法通常最多使用它来更新ObservableCollections。根据其中的内容,您甚至可以将
start
作为线程进程传递。但是请看下面IDisposable的好答案——这是最好的习惯用法。如果我稍后在start方法中调用dispatcher,我可以使用dispatcher将ui进程加入到ui线程吗?是的,我尝试过使用async/await,但问题是start有ui元素,所以它需要是sta,这样对ui来说就不起作用了谢谢它还没有完成长时间运行的任务,但我会玩它,看看我是否能想出一些办法,因为它不会抛出错误。运行该任务是否还有其他障碍?请放置断点并检查。这就是我所做的。你的代码看起来很好,我将不得不修改我的代码,使其工作,但它正在调用方法。再次感谢。哦,我还很新。当问题解决后,我需要做什么?如果你得到了答案,你可以点击绿色的勾号,将答案标记为正确答案。