【发布时间】:2015-09-22 06:07:45
【问题描述】:
我有一个 WPF 应用程序,它使用同一类的两个对象异步调用 Web 服务。来自调用的两个事件处理程序的结果响应集合应放入作为数据绑定到 UI 的同一个字典中。 我的问题是当 web 服务返回集合并尝试插入同一个字典时出现线程锁。
public class myClass : Window
{
public MyService serv1 {get;set;}
public MyService serv2 {get;set;}
public ObservableDictionary<string, MySertvice> dict = new ObservableDictionary<string, MySertvice>();
public ObservableDictionary<string, MySertvice> Dict_VM {get;set;}
public myClass()
{
InitializeComponent()
this.DataContext = Dict;
serv1 = new MyService("serviceA");
serv1.CallBack += CallBack;
serv2 = new MyService("serviceB");
serv2.CallBack += CallBack;
}
public Window_Loaded(object sender, WindowloadedEventArgs e)
{
serv1.DoServiceCallAsync();
Debug.WriteLine("- first call");
serv2.DoServiceCallAsync();
Debug.WriteLine("- second call");
}
public void CallBack(object sender, CallBackEventArgs e)
{
Debug.WriteLine("- callback");
foreach(var name in e.ResultCollection)
{
dict.Add(name, sender as MyService);
}
}
}
输出是:
- 第一次通话
- 第二次通话
- 回调
- 回调
我的问题是,使其线程安全的最佳方法是什么?
这只是一个示例,所以逻辑无关紧要。我想要 ResultCollection 的每个元素。我的第一个想法是将结果转移到队列或并发队列中,并让后台工作人员将其从队列中处理到字典中。我真的很想要最好的方法
【问题讨论】:
-
向集合中添加项目是否必须是线程安全的..?你能描述一个有问题的场景吗?我的意思是,为什么将对象(A,B,C)与对象(D,E,F)同时添加有问题。?您是否要求第一次调用 return 必须完成添加项目,然后第二次调用才能开始添加它的项目?
-
是的,它必须这样做。多个异步回调必须能够同时添加到对象中。这是一个包含两个服务的示例,实际上(我的真实世界场景)我有一个服务集合。它必须收集实时监控数据。处理单个服务的时间至关重要
-
为什么不使用 Dispatcher 将更新编组到 UI 线程上? Dispatcher 是线程安全的,可以很好地管理多个调用。您只能通过生成一个线程来为您提供结果的 ConcurrentQueue 提供服务来模拟它。
-
你能给我一个例子或链接吗?
标签: c# wpf asynchronous mvvm