MVVM Dispatcher UI无法响应

时间:2015-05-07 13:33:53

标签: c# wpf mvvm dispatcher

我遇到了一个非常简单的问题:

我使用MVVM灯构建MVVM应用程序。

当我进行大量计算时,我的UI没有响应。 我需要一个调度程序,因为我想访问一些依赖对象。

我尝试使用该代码:(可能因为我正在使用应用程序线程而无法工作?!)

Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
            {
                //LongTimeStuff
            }));

我也尝试过:

        DispatcherHelper.Initialize();
        DispatcherHelper.CheckBeginInvokeOnUI(() =>
        {
             //LongTimeStuff
        });

但在这里我遇到了问题,我的Dependency Objects在另一个线程中。

我在新线程的函数中做的所有这些事情:

   Thread CalculationThread = new Thread(this.Calculate);

谢谢!

5 个答案:

答案 0 :(得分:1)

Dispatcher BeginInvoke或InvokeAsync不运行任何单独的线程。它只向Dispatcher任务队列添加任务。但是调度程序队列总是在UI线程上处理。

这是你应该做的:

void CommandExecuted()
{
   Task.Run(() =>
   {
     //long running stuff

     Dispatcher.BeginInvoke(new Action(() =>
     {
       //access ui here
     }));
}

或使用异步模式:

    async void CommandExecuted()
    {
        await Task.Run(() =>
        {
            //long running stuff
        });
        //access ui here
    }

答案 1 :(得分:0)

在需要访问依赖关系对象时,在新的线程/任务中运行长时间的东西,然后调用主线程,例如:

private void button_Click(object sender, RoutedEventArgs e)
    {          
        Task.Run(() => {
            Thread.Sleep(3000);
            //LongTimeStuff
            Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
            {
                textBlock1.Text = "10";

            }));
        });
    }

答案 2 :(得分:0)

尝试更改DisptatcherPriority,如果您计划在之前开始处理另一个线程,则不需要BeginInvoke:

        Task.Factory.StartNew(() =>
        {
            for (int i = 0; i < 5; i++)
            {
                Thread.Sleep(2000);
                //LongTimeStuff
                Application.Current.Dispatcher.Invoke(DispatcherPriority.ApplicationIdle, new Action(() =>
                {
                    textblock.Text = DateTime.Now.ToString();

                }));
            }
        });

答案 3 :(得分:0)

您需要在另一个线程中完成工作,然后使用调度程序在完成后更新UI。这是一些演示的C#伪代码。

Public Sub Test()
    TestInner(Nothing)
End Sub

Public Sub TestInner(ByRef A As Object)
    Dim B As Object

    B = New Object
    A = B

    Debug.WriteLine(A Is B)
    'Insert breakpoint here
End Sub

答案 4 :(得分:0)

我得到了答案:

首先 - 我已经把我的“LongTimeStuff”从Dispatcher中删除了。

第二 - 我已经做了:Task.Sleep(1);在我的循环中突然它起作用了。 想知道为什么但它有效!