Maybe I don't understand something, but ...

There is a class (for example, MyClass ) that generates an event. For example, it is called EndedEvent .
There is also a UserControl in which an instance of the class Myclass . UserControl subscribes to the EndedEvent event when the button is EndedEvent . Below I will try to bring in the used pieces of code and describe the interaction.

Dispatcher Wrap:

 public static class FastDispatcher { static public void CodeBlock<T>(T Target, Action _codeBlock) where T : System.Windows.Threading.DispatcherObject { Target.Dispatcher.Invoke(_codeBlock); } } 

Control:

 public partial class MyConrol : UserControl { MyClass myClass; public SocialGetter() { InitializeComponent(); myClass= new MyClass(); ; } private void button_Click(object sender, RoutedEventArgs e) { myClass.EndedEvent+= myClass_EndedEvent; myClass.Start("строка"); } private void myClass_EndedEvent() { FastDispatcher.CodeBlock(this, () => { textBox1.Text = "OK"; myClass.EndedEvent -= myClass_EndedEvent; }); } } 

Class:

 public class MyClass { public delegate EndedEventDel(); public EndedEventDel EndedEvent; void Start(string str) { ActionDF.EndedEvent += ADF_EndedEvent; ActionDF.Add(str); } private void ADF_EndedEvent() { if (EndedEvent!= null) EndedEvent(this); ActionDF.EndedEvent -= ADF_EndedEvent; } } 

Dataflow queue:

 public static class ActionDF { public delegate EndedEventDel(); public EndedEventDel EndedEvent; public TransformBlock<string,string> actionblock //допустим void Start(string str) { actionblock = new TransfonmBlock<string,string>(n => { Threed.Sleep(2000); if(EndedEvent!=null) EndedEvent(); return ""; }); } public void Add(string str) { actionblock.Post(str); } } 

Then I put on the form 2 of my MyControl and click on each button. As a result, the OK message is displayed only on the MyControl in which I pressed the button first. If you make a reply from the event in the control and put it in the event of the button before the subscription, then everything works correctly.

Where can there be a mistake?

  • And why do you need Dispatcher.BeginInvoke(new Action(delegate (){ _codeBlock();})).Wait(); if you can just Dispatcher.Invoke(_codeBlock) ? - VladD
  • @VladD, I don `t know, maybe I was stuck, or I wrote it at 5 in the morning, but this did not fix the problem. - BwehaaFox
  • No, it should not fix the problem, it just looks significantly simpler, but does exactly the same thing. - VladD
  • @VladD, well, it's hard to argue with that :) - BwehaaFox

1 answer 1

I will assume that the problem is this: your ActionDF.EndedEvent event ActionDF.EndedEvent not report what exactly is completed.

Result:

  1. MyClass # 1 subscribes to ActionDF.EndedEvent and starts the first task via ActionDF.Add .
  2. MyClass # 2 also subscribes to ActionDF.EndedEvent and starts the second task.
  3. The first task ends, triggered ActionDF.EndedEvent .
  4. Both MyClass instances get it at the same time. Both unsubscribe from ActionDF.EndedEvent

In this situation, the execution should go wrong, but with the code that you gave, the output should be simultaneously on both controls. Recheck what happens in your reality.

  • What the doctor ordered! Thank you - BwehaaFox
  • @BwehaaFox: That's great! One less mystery. - VladD
  • @VladD and how to make sure that this situation does not exist? Just an interesting task - Fony Fazoulyanov
  • @FonyFazoulyanov: For example, pass a reference to the completed task in the event arguments in some way. Or do not use events at all, and when sending a task for execution, get Task<ResultT> . - VladD
  • @VladD thanks. - Fony Fazoulyanov