如何使代码“等待”,使用户仍然可以看到页面?

时间:2020-09-26 09:27:40

标签: c# wpf asynchronous

好吧,我将尝试使其变得简单,可以说我正在尝试使文本框背景在事件发生时以红色显示。

例如:

//Logic Class

private void SomeLogic() 
  {
    //some logic
    ...
    event() //trigger the event
    //some more logic
    ...
    event() //trigger the event again, it should not reach here until the last event is done
  }

在Main.xmal.cs上

//Gets triggered when invoking the event()
private async void ChangeRed()
{
  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;
}

注意:它的导入是task.delay将保持执行直到完成,因为该事件在整个“逻辑”中可能会发生多次

1 个答案:

答案 0 :(得分:0)

您的问题非常广泛且不明确。无法提供最合适的解决方案,因为您的真实问题和背景仍然未知。

我提供的两个简单的通用解决方案都需要将您希望在分区中执行的代码拆分。两种解决方案都需要可观察者与观察者之间的契约:观察者必须负责通知可观察者该事件的处理已完成。

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
}

解决方案1 ​​
向观察者公开细节。观察者需要了解相关成员(不建议用于库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();
}

解决方案2
实现自定义EventArgs,该自定义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); } } } 可以将事件设置为处理。这使侦听器可以隐式控制流(无需了解详细信息)。
在这种情况下,观察者必须遵循不成文的规则才能将事件设置为已处理状态(不建议用于库API)。

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
}

引发事件:

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;
}

处理事件:

WaitHandle

您可以改用一些list1 = [5,6,7,8],也可以使用更适合的同步机制。
再一次,由于您提出了一个非常广泛且不确定的问题,您只能得到一个非常模糊且不确定的答案。

我的建议是重新访问您的班级设计并进行重构以摆脱这种情况。您的问题是设计不良/没有设计的结果。