mic*_*eyt 10 .net c# asynchronous
我正在使用WeakEventManager<TEventSource, TEventArgs>
该类来订阅C#中的事件.事件订阅工作正常,但是WeakEventManager<TEventSource, TEventArgs>.RemoveHandler
从a 调用Task
并不总是删除处理程序 - 当事件触发时处理程序仍然执行的大部分时间(但不是全部).
以下示例说明了这一点.
public class EventSource
{
public event EventHandler Fired = delegate { };
public void FireEvent()
{
Fired(this, EventArgs.Empty);
}
}
class Program
{
private static bool added, removed, handled;
static void Main(string[] args)
{
for (int i = 1; i <= 100; i++)
{
added = removed = handled = false;
var source = new EventSource();
AddHandlerAsync(source).Wait();
RemoveHandlerAsync(source).Wait();
source.FireEvent();
if (removed && handled) Console.WriteLine("Event handled after removal!");
else Console.WriteLine("----------------------------");
}
Console.ReadKey();
}
private async static Task AddHandlerAsync(EventSource source)
{
await Task.Run(() =>
{
System.Windows.WeakEventManager<EventSource, EventArgs>.AddHandler(source, "Fired", HandleEvent);
added = true;
});
}
private async static Task RemoveHandlerAsync(EventSource source)
{
await Task.Run(() =>
{
System.Windows.WeakEventManager<EventSource, EventArgs>.RemoveHandler(source, "Fired", HandleEvent);
removed = true;
});
}
private static void HandleEvent(object sender, EventArgs e)
{
handled = true;
}
}
Run Code Online (Sandbox Code Playgroud)
处理程序一直被删除,但在大多数情况下仍然会处理事件.
我是否在调用这些方法时出错?这些方法是否支持异步调用?有没有可行的替代方法?
非常感谢您的帮助.
这是因为它WeakEventManager
存储在WeakEventTable
为当前线程(源)初始化的电流中:
[ThreadStatic]
private static WeakEventTable _currentTable; // one table per thread
Run Code Online (Sandbox Code Playgroud)
并且您使用线程池任务sheduler,这是默认的sheduler.它呼吁AddHandler
并RemoveHandler
在同一个线程的时候.但有时它会RemoveHandler
在另一个线程上调用,而另一个线程则WeakEventManager
没有请求EventSource
.
注意:如果类型继承DispatcherObject
此类型的实例,则取决于创建它们的线程.如果a DispatcherObject
是单例,则每个线程创建一个.
因此,如果您看到a,DispatcherObject
则仅从创建它的线程调用其方法.否则,你会遇到问题.