簡體   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