在我的WPF(C#)应用中,当按钮被用户按下,执行一个漫长的过程。 当按下按钮,直到完整的代码执行的窗口冻结,用户不能执行该窗口中的任何其他任务。 我怎样才能使按钮点击代码作为后台进程,使窗口成为响应用户。 我曾尝试以下方法,但没有成功。
private void btn_convert_Click(object sender, RoutedEventArgs e)
{
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
new Action(() => {
WorkerMethod();
}));
}
凡WorkerMethod与整个代码的功能。 任何suggessions。
问候,
桑杰塔
你实际上已经在这里做是要求UI线程通过调度来运行你的任务重。
您应该创建一个新的线程/任务,并让它运行你的后台方法:
Thread t = new Thread(() => WorkerMethod());
t.Start();
进一步信息,请阅读此:
WPF BackgroundWorker的调度与
在WPF理解“调度员”
如果您的目标.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
});
}
这里的答案,另一种方法是一个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
}
您正在呼吁的方法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`信息。
我想到另一种方式让我很骄傲的:在情况下,多线程有益处只允许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);
}
}
}
这里是我的建议替补席上的样子:
这里是我做替补,可以在其中找到组件的直接链接:
板凳解决方案直接下载
尝试使用BackgroundWorker的类。 你必须注册到DoWork的事件,并创建一个事件处理程序,你把所有的处理代码。你用的RunWorkerAsync方法启动工作。 另外还有一点可以报告你的员工进步“ReportProgress”的方法。 该RunWorkerCompleted会告诉你当你的员工做处理您的代码。 尝试的BackgroundWorker后在互联网上搜索,你会发现很多的例子来说明如何使用它