için UI olayları göndermek için SenkronizasyonKontext'i kullanma Bir çok çok iş parçacıklı arka plan görevleri yapan DLL'mden UI iş parçacığına geri dönen bir SynchronizationContext kullanıyorum.WinForms veya WPF
Tekil kalıpların favori olmadığını biliyorum, ancak foo'nun üst nesnesini oluştururken UI'nin SynchronizationContext öğesinin bir başvurusunu saklamak için şimdi kullanıyorum.
public class Foo
{
public event EventHandler FooDoDoneEvent;
public void DoFoo()
{
//stuff
OnFooDoDone();
}
private void OnFooDoDone()
{
if (FooDoDoneEvent != null)
{
if (TheUISync.Instance.UISync != SynchronizationContext.Current)
{
TheUISync.Instance.UISync.Post(delegate { OnFooDoDone(); }, null);
}
else
{
FooDoDoneEvent(this, new EventArgs());
}
}
}
}
Bu hiç WPF işe yaramadı (ana pencereden yem edilir) TheUISync örneklerini UI senkron asla geçerli SynchronizationContext.Current eşleşir. Windows formunda ben de aynı şeyi yaptığımda, bir invoke edildikten sonra eşleşecekler ve biz doğru dişe geri döneceğiz.
public class Foo
{
public event EventHandler FooDoDoneEvent;
public void DoFoo()
{
//stuff
OnFooDoDone(false);
}
private void OnFooDoDone(bool invoked)
{
if (FooDoDoneEvent != null)
{
if ((TheUISync.Instance.UISync != SynchronizationContext.Current) && (!invoked))
{
TheUISync.Instance.UISync.Post(delegate { OnFooDoDone(true); }, null);
}
else
{
FooDoDoneEvent(this, new EventArgs());
}
}
}
}
Yani bu örnek izleyecek kadar mantıklı umut gibi
Benim düzeltme, nefret, hangi görünüyor.
Bir şeyi gerçekten kilitlemediğiniz sürece, ne zaman kontrol ettiğinize bakılmaksızın, her zaman bu problemi yaşayabileceğinizi düşünüyorum. Ve bu, sınıfınızda sabitlenemeyen bir iş parçacığı sorunudur, olayınıza kablolama yapan sınıfta ele alınmalıdır (ya da etkinliğinizden çıkarılamıyor), ancak bir kilitleme nesnesi sağlamak zorundayım. Abone kullanabilir ve olayların senkronize olduğundan emin olmak için kullanabilirdim. –
Evet ve hayır. "kamu olayı ...", serbest iş parçacığı olarak adlandırılabileceğini varsayarsanız, kendi başına sorunları işliyor. İki iş parçacığının her ikisi de aynı anda aynı etkinliğe abone olursa, ikisi de çağrı listesine giremeyebilir. Bu yüzden varsayım, her zaman olayı ilk etapta ayarlamak için akıl yürütme protokolüne sahip olmanızdır. Bu tür en yaygın protokol, yalnızca UI iş parçacığı üzerinde bu tür olayları ayarlamaktır; bu durumda, hata düzeltmesi, güvenilir bir şekilde çalışır, oysa orijinal kod yoktur. Diğer taraftan, farklı bir protokol amaçlanmışsa, açık kilitlemeye ihtiyacınız olabilir. –
FooDoDoneEvent öğesinin boş olmadığından emin olmak için, gerçekten yapmak istediğiniz şeyin yerel bir değişkene FooDoDoneEvent öğesini ataması, boş olmadığını kontrol etmesi ve sonra FooDoDoneEvent (bu, yeni EventArgs()) çağırması gerektiğine inanıyorum. '. – Charles