这就是我现在所拥有的,但当我致电Dispatcher.BeginInvoke()
时,我的用户界面冻结了:
BackgroundWorker backgroundWorker = new BackgroundWorker();
backgroundWorker.WorkerSupportsCancellation = true;
backgroundWorker.WorkerReportsProgress = true;
ViewModel.GenerateReport(backgroundWorker, Dispatcher);
视图模型:
backgroundWorker.DoWork += delegate(object s, DoWorkEventArgs args)
{
try
{
ReportViewModel reportViewModel = new ReportViewModel(SessionContext, Mediator, reportDashboardViewModel.ReportRequest, false);
dispatcher.BeginInvoke((Action)(() =>
{
ReportPreviewView reportPreviewView = new ReportPreviewView(reportViewModel);
reportPreviewView.ReportName = reportDashboardViewModel.ReportRequest.Report.ReportName;
ReportView = reportPreviewView;
}));
}
catch (Exception exception)
{
backgroundWorker.ReportProgress(0, "There Was an Error generating the report");
backgroundWorker.CancelAsync();
throw;
}
};
backgroundWorker.RunWorkerAsync();
dispatcher.BeginInvoke
中的第一行导致我的UI
冻结。
ReportPreviewView reportPreviewView = new ReportPreviewView(reportViewModel);
注意:ReportPreviewView
为报告请求创建相关视图。可以是Devexpress
,C1
或pivot reports
。
我删除dispatcher.BeginInvoke
后,我收到此错误:
The calling thread must be STA, because many UI components require this.
所以我的问题是,我需要做些什么来解决这个问题?
使用BackgroundWorker
的全部原因是我的UI
始终保持响应。
我是multithreading
的新手,所以也许我的结构都错了......
答案 0 :(得分:2)
Disptacher.BeginInvoke启动使用Action ansynchronoulsy封装的代码,但BackgroundWorker也会更新Do_Work处理程序,因此您不应该使用它。
主要问题是您尝试从另一个线程访问UI实例,并且Windows不允许:只有主线程才能访问UI元素实例。
如果您使用的是Windows窗体,正确的方法是使用Control.Invoke。
答案 1 :(得分:0)
故事的道德,需要在UI线程上创建所有UI元素!
话虽如此,如果创建UI元素需要很长时间,UI将会冻结。承担所有繁重的工作并将其放入Task
或BackgroundWorker
。
然后你会有一个响应更快的用户界面。