我有一个应用程序从服务器获取数据并将结果提供给用户。 提取的数据非常大,有时会阻止UI。我正在使用调度程序使其异步。
以下是代码段: -
private void GetData(object sender, RoutedEventArgs e)
{
List<result> data=new List<result>;
DispatcherObject obj= Dispatcher.BeginInvoke(DispatcherPriority.Background,(ThreadStart)delegate
{
data =Data.fetch_data(id, name, url);
});
if(obj.Completed){
MessageBox.Show("Done!");
}
}
但代码提示错误
&#34;无法隐式转换类型 &#39; System.Windows.Threading.DispatcherOperation&#39;至 &#39; System.Windows.Threading.DispatcherObject&#39; &#34;
无论如何,当后台任务完成时,用户是否可以收到通知?
编辑: -
这是async / await代码
private async void GetData(object sender, RoutedEventArgs e)
{
Task<List<result>> T =Task<List<resultsummary>>.Factory.StartNew(() => data==Data.fetch_data(id, name, url));
await T;
}
但它给出了错误&#34;&#34;调用线程无法访问此对象,因为另一个线程拥有它。&#34;
答案 0 :(得分:1)
调用Dispatcher.BeginInvoke
使不使您能够在后台线程上执行异步操作,除非您在后台线程上初始化了Dispatcher
对象。因此,不是使用Dispatcher
来执行您想要的操作,而是为了在后台线程上获取数据,然后将该数据从后台线程传递到UI线程,您可以使用Task
class。
Task.Factory.StartNew((Func<YourDataType>)delegate()
{
// Fetch data on background thread here (return YourDataType, whatever that is)
return DataAccessClass.GetData();
}).ContinueWith((Task<YourDataType> task) =>
{
// Update controls with result on UI thread here
YourUiProperty = task.Result;
}, TaskScheduler.FromCurrentSynchronizationContext());
显然,您需要将YourDataType
类型替换为您的数据类型。
答案 1 :(得分:0)
使用.Net 4.5和VS2013,我建议使用async和await。
通过在Dispatcher上执行fetch_data操作,您将使用获取操作显式阻止UI线程。
private async void GetData(object sender, RoutedEventArgs e)
{
// fetch the data in a Background Task and release the UI Thread.
List<result> data = await Task.Run<List<result>>(() => Data.fetch_data(id, name, url));
// when completed return to the UI Thread.
this.MyListBox.ItemsSource = data;
}
更好的做法是建立一个返回Task<IEnumerable<result>>