让WPF UI响应当执行按钮点击(Make wpf UI responsive when butto

2019-08-17 14:30发布

在我的WPF(C#)应用中,当按钮被用户按下,执行一个漫长的过程。 当按下按钮,直到完整的代码执行的窗口冻结,用户不能执行该窗口中的任何其他任务。 我怎样才能使按钮点击代码作为后台进程,使窗口成为响应用户。 我曾尝试以下方法,但没有成功。

private void btn_convert_Click(object sender, RoutedEventArgs e)
{
    Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, 
    new Action(() => { 

         WorkerMethod();
    }));
}

凡WorkerMethod与整个代码的功能。 任何suggessions。

问候,
桑杰塔

Answer 1:

你实际上已经在这里做是要求UI线程通过调度来运行你的任务重。

您应该创建一个新的线程/任务,并让它运行你的后台方法:

Thread t = new Thread(() => WorkerMethod());
t.Start();

进一步信息,请阅读此:

WPF BackgroundWorker的调度与

在WPF理解“调度员”



Answer 2:

如果您的目标.NET 4.5,你可以使用async/await让你的UI响应:

private async void btn_convert_Click(object sender, RoutedEventArgs e)
{
    await WorkerMethod();
}

修改您的WorkerMethod

private Task WorkerMethod()
{
    return Task.Run(() =>
        {
           // your long running task here
        });
}


Answer 3:

这里的答案,另一种方法是一个BackgroundWorker。 它有它的完成后并返回到GUI线程的好处。

private void btn_convert_Click(object sender, RoutedEventArgs e)
{
    BackgroundWorker worker = new BackgroundWorker();
    worker.DoWork += WorkerMethod;
    worker.RunWorkerCompleted += WorkerEnded;
    worker.RunWorkerAsync();
}

private void WorkerMethod()
{
    // New thread, cannot access GUI
}

private void WorkerEnded()
{
    // Back on the GUI Thread
    // Worker is finished
}


Answer 4:

您正在呼吁的方法UI-Dispatcher ,这将使UI冻结。 创建使用在点击事件的新线程

private void btn_convert_Click(object sender, RoutedEventArgs e)
    {
         Thread t = new Thread(new ThreadStart(WorkerMethod));
         //assign STA or MTA, etc....
         t.Start();
    }

看看这里关于“System.Threading.Thread`信息。



Answer 5:

我想到另一种方式让我很骄傲的:在情况下,多线程有益处只允许IHM动画的进度条,如果用户不应该与IHM互动suring进程或者如果没有时间去developp多线程,你不能让你的应用程序没有反馈冻结:

你可以开发射入创建另一个窗口,显示该装载机在冻结窗口的中间另一个STA线程加载器。

下面是我所取得的文章,这样的解决方案的实施后:

http://charly-studio.com/blog/a-loader-for-wpf-long-ui-process/

下面是我如何使用我的组件:

private void MainWindow_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    // Long UI process context
    using (new LongUIProcessContext("Wait while loading..."))
    {
        Thread.Sleep(2000);

        // Sub long ui process context
        using (new LongUIProcessContext("Wait while loading 2..."))
        {
            Thread.Sleep(2000);
        } 

        // Another sub long ui process context
        using (new LongUIProcessContext("Wait while loading 3..."))
        {
            Thread.Sleep(2000);
        }
    }
}

这里是我的建议替补席上的样子:

这里是我做替补,可以在其中找到组件的直接链接:

板凳解决方案直接下载



Answer 6:

尝试使用BackgroundWorker的类。 你必须注册到DoWork的事件,并创建一个事件处理程序,你把所有的处理代码。你用的RunWorkerAsync方法启动工作。 另外还有一点可以报告你的员工进步“ReportProgress”的方法。 该RunWorkerCompleted会告诉你当你的员工做处理您的代码。 尝试的BackgroundWorker后在互联网上搜索,你会发现很多的例子来说明如何使用它



文章来源: Make wpf UI responsive when button click is performed