Your question is very broad and unspecific. It is not possible to give you the best suited solution as your true problem and context remains unknown.
Both simple generic solutions I provide, require to split up the code you wish to execute in partitions. Both solutions require a contract between observable and observer: the observer has to take the responsibility to notify the observable that handling the event is completed.
private void BeginSomeLogic()
{
//some logic
...
event() //trigger the event
}
// Trigger the event again
// It should not reach here until the last event is done
public void EndSomeLogic()
{
//some logic
...
event() //trigger the more events
}
Solution 1
Exposes details to the observer. Observer needs to know the relevant member (not recommended for library API).
private async void ChangeRedOnEvent(object sender, EventArgs e)
{
Textbox1.Background = Brushes.Red;
await Task.Delay(2000); //supposed to make program wait 2 seconds so we could see the change
Textbox1.Background = Brushes.White;
// Continue execution on the event source.
(sender as MyEventSource).EndSomeLogic();
}
Solution 2
Implement a custom EventArgs
that allows to set the event to handled. This enables the listener to control the flow implicitly (without knowing details).
In this scenario the observer must follow the unwritten rule to set the event to a handled state (not recommended for library API).
public class SomeEventArgs : EventArgs
{
public SomeEventArgs(int listenerCount)
{
this.ListenerCount = listenerCount;
}
private int ListenerCount { get; set; }
private bool isHandled;
public bool IsHandled
{
get => this.isHandled;
set
{
this.isHandled = value;
OnHandledChanged();
}
}
public event EventHandler HandledChanged;
protected virtual void OnHandledChanged()
{
if (--this.ListenerCount < 1)
{
this.HandledChanged?.Invoke(this, EventArgs.Empty);
}
}
}
Raise the event:
private SomeEventArgs HandledEventArgs { get; set; }
private void BeginSomeLogic()
{
//some logic
...
EventHandler<SomeEventLogicArgs> handler = this.SomeEvent;
if (handler == null)
{
return;
}
this.HandledEventArgs = new SomeEventArgs(handler.GetInvocationList().Length);
this.HandledEventArgs.HandledChanged += EndSomeLogic;
this.SomeEvent?.Invoke(this, this.HandledEventArgs) //trigger the event
}
// Trigger the event again
// It should not reach here until the last event is done
public void EndSomeLogic(object sender, EventArgs e)
{
this.HandledEventArgs.HandledChanged -= EndSomeLogic;
//some logic
...
event() //trigger the more events
}
Handle the event:
private async void ChangeRedOnEvent(object sender, SomeEventArgs e)
{
Textbox1.Background = Brushes.Red;
await Task.Delay(2000); //supposed to make program wait 2 seconds so we could see the change
Textbox1.Background = Brushes.White;
// Continue execution on the event source.
e.IsHandled = true;
}
You can use some WaitHandle
instead or what ever synchronization mechanism is better suited.
Again since you have asked a very broad and unspecific question you can only get a very vague and unspecific answer.
My recommendation is to revisit your class design and refactor it to get rid of this situation. Your problem is the result of a bad/no design.