Weg*_*ged 1 c# parallel-processing events delegates task-parallel-library
我有一个事件,当被解雇时,订阅者执行一些可能需要一段时间才能返回的数据库代码.我想并行执行所有订阅者委托.我正在尝试使用Parallel.Foreach,但我无法得到任何建议吗?
我目前正在尝试沿着这些方向做点什么.
Parallel.ForEach(FacilitiesChanged.GetInvocationList(),某种lambda表达式)
其中FacilitiesChanged是一个事件.
我有一个事件,当被解雇时,订阅者执行一些可能需要一段时间才能返回的数据库代码.我想并行执行所有订阅者委托.我正在尝试使用Parallel.Foreach,但我无法得到任何建议吗?
我建议将并行性推送到订阅者端,而不是尝试并行调用委托.
让订阅者做:
private void OnMyEvent(object sender, EventArgs e)
{
Task.Factory.StartNew( () =>
{
// Your DB code logic here...
});
}
Run Code Online (Sandbox Code Playgroud)
这将导致事件异步发生.
如果你必须等待返回类型,我个人会一起避免事件.这里的问题是事件订户不会阻止固有的期望.允许事件阻止将违反预期,并导致问题.
相反,我建议使用一种控制反转形式,并通过接口而不是事件来处理.然后,与标准事件使用情况相比,观察者模式的变化有所不同:
// Publisher side - add methods to add/remove "subscribers":
public void AddListener(IDatabaseOperation op)
{
lock(syncObj) // thread safety may be an issue...
this.listeners.Add(op);
}
private void OnEvent()
{
lock(syncObj)
{
Parallel.ForEach(this.listeners, l => l.DoOperation());
}
}
Run Code Online (Sandbox Code Playgroud)
如果您必须在发布端多线程调用您的调用,可以通过以下方式完成:
private void RaiseMyEvent(MyEventArgs e)
{
var handler = this.TheEvent;
if (handler != null)
{
var tasks = new List<Task>();
foreach(var yourEvent in handler.GetInvocationList().Cast<EventHandler<MyEventArgs>())
tasks.Add(Task.Factory.StartNew( () => yourEvent(this, e)));
// Optionally wait here... Removing the following makes this asynchronous
Task.WaitAll(tasks.ToArray());
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3374 次 |
| 最近记录: |