And*_*ndy 5 wpf multithreading mvvm-light
我遇到从db获取数据并在UI中异步显示的问题.我正在使用MVVM灯,当我单击按钮时,在ViewModel中触发操作:
private void SearchQuery(string query)
{
_redisModel.GetFriendsListAsync(query);
}
Run Code Online (Sandbox Code Playgroud)
在某些时候,GetFriendsListCompleted由后台线程调用,通知viewmodel作业已完成.此时我需要更新ListBox ItemSource.但是当我尝试更新时,我得到 "调用线程无法访问此对象,因为另一个线程拥有它" 我已经尝试过 Dispatcher.CurrentDispatcher.Invoke(),App.Current.Dispatcher.Invoke()和不同的魔法,但它仍然无法正常工作.
我试图将UI调度程序提供给ViewModel,然后从那里调用它 - 没有用.
private string filterText = string.Empty;
public string FilterText
{
get { return filterText; }
set
{
filterText = value;
this.RaisePropertyChanged(() => this.FilterText);
this.FriendsList.View.Refresh(); // Here where exception is happening.
}
}
Run Code Online (Sandbox Code Playgroud)
我试图改变这一行
Dispatcher.Invoke(DispatcherPriority.Normal,new Action(()=> this.FriendsList.View.Refresh())); - 还是一样.
我正在使用Telerik ListBox来显示项目.FriendList是CollectionViewSource(http://www.telerik.com/help/wpf/radlistbox-overview.html).当我在WPF控件示例中使用Telerik示例时,它可以正常工作.当我使用异步方法时,问题开始出现.视图类型是System.ComponentModel.ICollectionView,它用于过滤和分组.
我还尝试将ObservableCollection分配给ListBox的Items属性,但它也不起作用.
关于_redisModel.GetFriendsListAsync如何工作的更多细节:最后(在所有调用链之后)它最终在这里:
public GetAsyncResult(Func<T> workToBeDone, Action<IAsyncResult> cbMethod, Object state)
{
_cbMethod = cbMethod;
_state = state;
QueueWorkOnThreadPool(workToBeDone);
}
ThreadPool.QueueUserWorkItem(state =>
{
try
{
_result = workToBeDone();
}
catch (Exception ex)
{
_exception = ex;
}
finally
{
UpdateStatusToComplete(); //1 and 2
NotifyCallbackWhenAvailable(); //3 callback invocation
}
});
Run Code Online (Sandbox Code Playgroud)
在viewmodel中我有方法:
private void GetFriendsListCompleted(object sender, ResultsArgs<Friend> e)
{
if (!e.HasError)
{
var curr = e.Results;
if (curr != null)
{
this.FriendsList= new CollectionViewSource();
this.FriendsList.Source = list;
this.FriendsList.Filter += this.FriendFilter;
FilterText = "";
Dispatcher.Invoke(DispatcherPriority.Normal, new Action(
() => this.FriendsList.View.Refresh()));
}
}
Run Code Online (Sandbox Code Playgroud)
有人可以帮帮我吗?谢谢
您正在CollectionViewSource一个线程中创建并在另一个线程(调度程序线程)中刷新它。将您的更新GetFriendsListCompleted为
private void GetFriendsListCompleted(object sender, ResultsArgs<Friend> e)
{
if (!e.HasError)
{
var curr = e.Results;
if (curr != null)
{
Dispatcher.Invoke(DispatcherPriority.Normal, new Action(
() => {
this.FriendsList= new CollectionViewSource();
this.FriendsList.Source = list;
this.FriendsList.Filter += this.FriendFilter;
FilterText = "";
this.FriendsList.View.Refresh();
}));
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7200 次 |
| 最近记录: |