[英]C# I'm getting null from Task or Dispatcher
I have this code: 我有以下代码:
public void OpenReport(XtraReport report, int zoomMode)
{
//Show loading animation.
MainInterfaceViewModel.State = States.Busy;
//Load the report, then navigate to the ReportViewer
Task tsk = Task.Factory.StartNew(() => LoadReport(report, zoomMode));
//After completing the task hide the loading animation
tsk.ContinueWith(obj => MainInterfaceViewModel.State = States.Idle);
}
private void LoadReport(XtraReport report, int zoomMode)
{
ReportViewerViewModel reportViewerViewModel;
reportViewerViewModel = new ReportViewerViewModel(report, zoomMode);
ReportViewer.Dispatcher.Invoke(new Action(() => ReportViewer.DataContext = reportViewerViewModel)) ;
Frame.Navigate(ReportViewer);
}
But when the OpenReport method is executed I get an empty ReportViewer, why I'm getting this problem while I passed the Report to the method ? 但是,当执行OpenReport方法时,我得到一个空的ReportViewer,为什么在将Report传递给该方法时却遇到此问题? The image bellow shows the result I get.
下面的图像显示了我得到的结果。
The results I'm getting 我得到的结果
EDIT: 编辑:
When I change the OpenReport method to the following code I get the report shown inside the report viewer but the UI freezes when the report is preparing (about 3 seconds). 当我将OpenReport方法更改为以下代码时,我将报表显示在报表查看器中,但在报表准备时(大约3秒)UI会冻结。
public void OpenReport(XtraReport report, int zoomMode)
{
//Show loading animation.
MainInterfaceViewModel.State = States.Busy;
//Load the report
ReportViewerViewModel reportViewerViewModel;
reportViewerViewModel = new ReportViewerViewModel(report, zoomMode);
ReportViewer.DataContext = reportViewerViewModel;
//Navigate to the ReportViewer
Frame.Navigate(ReportViewer);
//Hide the loading animation.
MainInterfaceViewModel.State = States.Idle;
}
As @TotaloDotoNeto tried to point out, Task.StartNew
is sometimes dangerous method to use, as it uses the TaskScheduler.Current
not TaskScheduler.Default
property, which is quite uneasy to deal with. 至于@TotaloDotoNeto试图指出,
Task.StartNew
有时使用危险的方法,因为它使用TaskScheduler.Current
不TaskScheduler.Default
财产,这是相当不易对付。 Stephen Cleary has a great article regarding differences between StartNew
and Run
methods ., and if you are interested, here is another one from Stephen Toub . Stephen Cleary 撰写了一篇很棒的文章,介绍了
StartNew
和Run
方法之间的区别 。如果您感兴趣的话,这是Stephen Toub的另一篇文章 。 So, first of all I suggest you to switch to Run
method: 因此,首先我建议您切换到
Run
方法:
Task tsk = Task.Run(() => LoadReport(report, zoomMode));
Second, let's see what your code is doing: you start a Task
, and inside that task your are using some background logic ( Dispatcher.Invoke
) and foreground logic ( Frame.Navigate
). 其次,让我们看看您的代码在做什么:启动一个
Task
,然后在该任务内使用一些后台逻辑( Dispatcher.Invoke
)和前景逻辑( Frame.Navigate
)。 I think that that problem you have is caused by your code for Frame
being executed not in UI-thread. 我认为您遇到的问题是由于您的
Frame
代码未在UI线程中执行而导致的。 So, you have two options: 因此,您有两个选择:
// add the Navigate method to the invoking delegate
ReportViewer.Dispatcher.Invoke(new Action(() =>
{
ReportViewer.DataContext = reportViewerViewModel;
Frame.Navigate(ReportViewer);
}));
or make your code async
, something like this: 或使您的代码
async
,如下所示:
public async Task OpenReport(XtraReport report, int zoomMode)
{
// Show loading animation.
MainInterfaceViewModel.State = States.Busy;
// Asynchronously wait for the model to load
var task = await Task.Run(() => LoadReport(report, zoomMode));
// process the model after it's being loaded
ReportViewer.DataContext = task.Result;
// Navigate to the ReportViewer
Frame.Navigate(ReportViewer);
// After completing the task hide the loading animation
MainInterfaceViewModel.State = States.Idle;
}
private async Task<ReportViewerViewModel> LoadReport(XtraReport report, int zoomMode)
{
return new ReportViewerViewModel(report, zoomMode);
}
Note that in second case you have to rewrite your code to async
all the way . 请注意,在第二种情况下,您必须重写代码以始终保持
async
。 Another article about async/await
keywords and some useful article about how to do not block on async code , if you are interested in this theme. 如果您对此主题感兴趣的话, 另一篇有关
async/await
关键字的文章和一些有关如何不阻止异步代码的有用文章。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.