Reputation: 4307
My small WPF code is giving me this error The calling thread cannot access this object because a different thread owns it I know what exactly it is saying but I am unable to understand how can I fix it. I have tried different things but no luck and I admit that I am not good in Task library.
This is what I am trying to achieve.
here is my code
public partial class DocListView : UserControlListBase
{
private ScecoBillDataScope _scecoBillDataScope;
public EntityCollection<ScecoBillEntity> ScecoBills = new EntityCollection<ScecoBillEntity>();
public DocListView()
{
InitializeComponent();
LoadData();
}
private async void LoadData()
{
await Task.Run(() =>
{
_scecoBillDataScope.FetchData();
});
var collectionView = CollectionViewSource.GetDefaultView(_scecoBillDataScope.ScecoBills);
await Dispatcher.BeginInvoke(new ThreadStart(()=> LayoutRoot.DataContext = collectionView));
}
private void BbiRefresh_ItemClick(object sender, DevExpress.Xpf.Bars.ItemClickEventArgs e)
{
_scecoBillDataScope.Reset();
LoadData();
e.Handled = true;
}}
Actually the error is appearing when I click the Refresh button at this line _scecoBillDataScope.FetchData(); Please advice.
Upvotes: 0
Views: 521
Reputation: 457167
Since your collection items are data bound to your view, you have to treat them as part of your UI.
Try loading a new collection from within Task.Run
, and then copying them over your existing items while on the UI thread. So, the new collection is built on a thread pool thread (Task.Run
), and then the data-bound collection items are modified from the UI thread.
Upvotes: 0
Reputation: 1136
It looks like you want to do something in UI Thread.
As You know You can use Dispatcher
class.
But There is another way to ask something to UI Thread.
var uiThread = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.StartNew(() =>
{
// I assumed that It returns boolean value
_scecoBillDataScope.FetchData();
}).ContinueWith(x =>
{
// Here you can put the code to work on the UI thread.
if (x.Result)
{
var collectionView = CollectionViewSource.GetDefaultView(_scecoBillDataScope.ScecoBills);
LayoutRoot.DataContext = collectionView;
}
}, uiThread);
I hope it helps.
thank you.
Upvotes: 0
Reputation: 16148
Your problem is this line:
await Dispatcher.BeginInvoke(new ThreadStart(()=> LayoutRoot.DataContext = collectionView));
You're just creating a new thread, you have to actually dispatch on the GUI thread:
Application.Current.Dispatcher.Invoke(() =>
{
LayoutRoot.DataContext = collectionView;
});
Upvotes: 1