C# içindeki olaylara abone olmak için WeakEventManager<TEventSource, TEventArgs>
sınıfını kullanıyorum. Olay aboneliği iyi çalışıyor, ancak numaralı telefondan WeakEventManager<TEventSource, TEventArgs>.RemoveHandler
numaralı çağrıları her zaman işleyiciyi kaldırmaz - çoğu olay işleyicisi işlendikten sonra yürütülürken gerçekleşen çoğu (ama hepsi değil).WeakEventManager RemoveHandler, zaman uyumsuz olarak çağrıldığında her zaman çalışmaz
Bu, aşağıdaki örnekte gösterilmiştir.
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;
}
}
işleyicisi
ancak çoğu durumda olay hala işlenir, tüm zaman kaldırılır.Bu yöntemlerin çağrılma biçiminde bir hata mı yapıyorum? Bu yöntemler senkronize olmayan olarak adlandırılmayı destekliyor mu? Çalışacak alternatif bir yaklaşım var mı?
Yardımlarınız için şimdiden teşekkür ederiz.
[ThreadStatic]
private static WeakEventTable _currentTable; // one table per thread
Ve varsayılan sheduler olan iş parçacığı havuzu görev sheduler kullanın:
Teşekkürler, neden bu davranışı görüyorum açıklıyor. İşleyicilerin aynı iş parçacığı üzerinde kaldırılması için Add/RemoveHandler aramamı nasıl değiştiririm? – mickeyt
'AddHandler' ve' RemoveHandler' yöntemlerini çağırmak için 'Application.Current.Dispatcher' kullanın. –
Bu örnekte 'Application.Current' yoktur. 'DispatcherObject' hakkında ipucu için teşekkürler - çok yararlı! – mickeyt