MVVM 调度程序 UI 没有响应
MVVM Dispatcher UI not responisve
我 运行 在一个可能很简单的问题中:
我用 MVVM light 构建了一个 MVVM 应用程序。
当我进行大量计算时,我的 UI 没有响应。
我需要一个调度程序,因为我想访问一些依赖对象。
我尝试使用该代码:(可能无法工作,因为我使用的是应用程序线程?!)
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
{
//LongTimeStuff
}));
我也试过:
DispatcherHelper.Initialize();
DispatcherHelper.CheckBeginInvokeOnUI(() =>
{
//LongTimeStuff
});
但是这里我遇到了问题,我的依赖对象在另一个线程中。
我在新线程的函数中所做的所有这些事情:
Thread CalculationThread = new Thread(this.Calculate);
谢谢!
运行 新 Thread/Task 中的长期内容,只要您需要访问依赖对象,然后调用主线程,例如:
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";
}));
});
}
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
}
尝试更改 DispatcherPriority,如果您计划在之前开始处理另一个线程,则不需要 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();
}));
}
});
您需要在另一个线程中完成工作,然后使用调度程序在完成后更新您的 UI。这是一些演示的 C# 伪代码。
// we're in the UI thread here
PleaseWait = true; // indicate to the user we'll be back soon
var whatever = GetStuffFromTheUIThatWeNeedInTheOtherThreadLol();
Task.Run(() =>
{
// here we're on a background thread
var result = OurLongRunningOperation(whatever);
Application.Current.Dispatcher.BeginInvoke(
DispatcherPriority.Normal, new Action(() =>
{
// we're back on the UI thread here
UpdateUIWithResultsOfLongTimeOperationDerp(result);
PleaseWait = false;
}));
});
// snip
我得到了答案:
首先 - 我确实从 Dispatcher 中取出了我的 "LongTimeStuff"。
其次 - 我已经做了:Task.Sleep(1);
在我的循环中,突然它起作用了。
想知道为什么但它有效!
我 运行 在一个可能很简单的问题中:
我用 MVVM light 构建了一个 MVVM 应用程序。
当我进行大量计算时,我的 UI 没有响应。 我需要一个调度程序,因为我想访问一些依赖对象。
我尝试使用该代码:(可能无法工作,因为我使用的是应用程序线程?!)
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
{
//LongTimeStuff
}));
我也试过:
DispatcherHelper.Initialize();
DispatcherHelper.CheckBeginInvokeOnUI(() =>
{
//LongTimeStuff
});
但是这里我遇到了问题,我的依赖对象在另一个线程中。
我在新线程的函数中所做的所有这些事情:
Thread CalculationThread = new Thread(this.Calculate);
谢谢!
运行 新 Thread/Task 中的长期内容,只要您需要访问依赖对象,然后调用主线程,例如:
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";
}));
});
}
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
}
尝试更改 DispatcherPriority,如果您计划在之前开始处理另一个线程,则不需要 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();
}));
}
});
您需要在另一个线程中完成工作,然后使用调度程序在完成后更新您的 UI。这是一些演示的 C# 伪代码。
// we're in the UI thread here
PleaseWait = true; // indicate to the user we'll be back soon
var whatever = GetStuffFromTheUIThatWeNeedInTheOtherThreadLol();
Task.Run(() =>
{
// here we're on a background thread
var result = OurLongRunningOperation(whatever);
Application.Current.Dispatcher.BeginInvoke(
DispatcherPriority.Normal, new Action(() =>
{
// we're back on the UI thread here
UpdateUIWithResultsOfLongTimeOperationDerp(result);
PleaseWait = false;
}));
});
// snip
我得到了答案:
首先 - 我确实从 Dispatcher 中取出了我的 "LongTimeStuff"。
其次 - 我已经做了:Task.Sleep(1);
在我的循环中,突然它起作用了。
想知道为什么但它有效!