繁体   English   中英

如何让代码“等待”并且用户仍然能够看到页面?

[英]How to make code "wait" and still user will be able to see the page?

好的,我会尽量简化,假设我正在尝试使文本框背景在事件发生时显示为红色。

例如:

//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 将保持执行直到它完成,因为事件可能会在整个“逻辑”中发生多次

您的问题非常广泛且不具体。 由于您的真正问题和背景仍然未知,因此无法为您提供最合适的解决方案。

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

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
向观察者公开细节。 Observer 需要知道相关成员(不推荐用于库 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 ,允许将事件设置为已处理。 这使侦听器能够隐式地控制流(不知道细节)。
在这种情况下,观察者必须遵循不成文的规则将事件设置为已处理状态(不推荐用于库 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);
    }
  }
}

引发事件:

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或者更适合的同步机制。
同样,由于您提出了一个非常广泛和不具体的问题,因此您只能得到一个非常模糊和不具体的答案。

我的建议是重新审视您的类设计并对其进行重构以摆脱这种情况。 您的问题是糟糕/无设计的结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM