我有一个应用程序从API异步接收事件,并可以在此API上同步调用方法。锁定事件处理的最有效的设计模式
为了线程安全的目的,我需要每个同步函数和应用程序中的每个事件处理程序都被锁定。
然而,调用API方法同步可能导致的API,以提高在不同的线程事件,等待他们返回之前进行处理。
因此,这可能会导致死锁的API将等待要处理的事件继续,但在我的课同步对象将由两个不同的线程被击中,程序会挂起。
我的当前的想法是,而不是锁定的事件处理程序,尝试锁定和如果不可行,(例如,如果从在另一个线程同步调用该事件的结果),以缓冲在队列/消息泵事件。
对上同步函数调用释放锁之前,我会再调用一个ProcessPendingEvents()
功能,使事件可能没有僵局进行处理。
对于这种情况,您是否有任何设计模式?我对任何事情都很开放。
下面是一个简单的例子来说明我目前的试验性实施。我真的瞄准有一类,将表现在单线程方式尽可能:
class APIAdapter {
readonly object AdapterLock = new object();
private readonly ConcurrentQueue<Tuple<object, EventArgs>> PendingEvents = new ConcurrentQueue<Tuple<object, EventArgs>>();
ExternalAPI API = new ExternalAPI();
APIAdapter() {
ExternalAPI.Data += ExternalAPI_Data;
}
public void RequestData() {
lock (this.AdapterLock) {
this.ExternalAPI.SynchronousDataRequest(); //Will cause the API to raise the Data event would therefore deadlock if I had a simple lock() in ExternalAPI_Data.
this.ProcessPendingEvents();
}
}
private void ExternalAPI_Data(object sender, EventArgs e) {
if (!Monitor.TryEnter(this.AdapterLock)) {
this.PendingEvents.Enqueue(Tuple.Create(sender, e));
return;
}
Console.Write("Received event.");
Monitor.Exit(this.AdapterLock);
}
private void ProcessPendingEvents() {
Tuple<object, EventArgs> ev;
while (this.PendingEvents.TryDequeue(out ev)) {
ExternalAPI_Data(ev.Item1, ev.Item2);
}
}
}
看那'ConcurrentQueue'类,这可能是在这种情况下,事件流之间的调停人。或者,[Rx](http://msdn.microsoft.com/en-us/data/gg577609.aspx)也许能够帮助您,因为它可以将事件视为来源。 –
这就是我现在使用的实现。我有一个很好的设计模式,或者我应该想到完全不同的东西吗? –
对我来说看起来不错。 (不喜欢一些命名约定,但这不是问题的关键......) –