2017-10-05 101 views
0

我正在處理一個WPF應用程序,在該應用程序中,只要數據綁定到滑塊的屬性發生更改,我就需要執行冗長的操作。有沒有簡單的方法來爲這個操作排隊異步任務,但確保只有最近排隊的任務運行?C#隊列最新異步任務

+0

你問如何爲*油門*事件由滑塊解僱?這與排隊不同。 .NET的機制允許你排列數據進行處理([ActionBlock ](https://msdn.microsoft.com/en-us/library/hh194684(v = vs.110).aspx)),只保留一個([BroadcastBlock ](https://msdn.microsoft.com/en-us/library/hh160447(v = vs.110).aspx)或限制事件流,因此每X或T只有一個事件秒通過[Observable.Throttle](https://msdn.microsoft.com/en-us/library/hh229400(v = vs.103).aspx)。這些*不同。我會說你想節流 –

+0

節流確實聽起來像是一個很好的解決方案,你能提供一個我將如何實現的例子嗎? –

回答

0

我設法創建一個使用Task.ContinueWith()一個任務鏈來解決我的問題。線程安全計數器確保只有鏈中的最後一個任務實際運行。

using System; 
using System.Threading; 
using System.Threading.Tasks; 

namespace WpfApp1 
{ 
    public class AsyncTaskRunner 
    { 
     #region Member Variables 

     Task m_TaskChain; 
     int m_TaskCount; 

     #endregion 

     #region Constructors 

     public AsyncTaskRunner() 
     { 
      //Initialize the member variables 
      m_TaskChain = Task.CompletedTask; 
      m_TaskCount = 0; 
     } 

     #endregion 

     #region Public Methods 

     public void Run(Action action) 
     { 
      //Add a continuation to the task chain using the specified action 
      Interlocked.Increment(ref m_TaskCount); 
      m_TaskChain = m_TaskChain.ContinueWith((prevTask) => 
      { 
       //Call the action if we're the last task in the task chain 
       if (Interlocked.Decrement(ref m_TaskCount) == 0) 
       { 
        action(); 
       } 
      }); 
     } 

     public async Task WaitAsync() 
     { 
      //Wait for the asynchronous task chain to finish 
      await m_TaskChain; 
     } 

     #endregion 
    } 
} 
2

您可以使用單個任務,取消它,然後重新分配一個新任務。該任務可以用延遲被鏈接去抖滑塊:

CancellationTokenSource cancel; 
Task task; 
... 

cancel?.Cancel(); 
cancel?.Dispose(); 
cancel = new CancellationTokenSource(); 
task = Task.Delay(3000, cancel.Token).ContinueWith(...); 
+0

在這種情況下,冗長的任務是將數據推送到設備,因此取消它會產生令人討厭的副作用 –

+0

@ NeilThiessen我編輯了我的答案,因此它只取消延遲任務。 – mtman

+1

您也可以延遲更新o f綁定,通過添加一個['Delay'](https://msdn.microsoft.com/en-us/library/system.windows.data.bindingbase.delay%28v=vs.110%29.aspx?f = 255&MSPPError = -2147217396)。這對於可以快速更改其值的屬性非常有用。延遲計時器從第一次更新開始,但只會在計時器結束後實際更新支持屬性,但會以*最新*值進行更新。您可以像這樣使用它'''' –

0

您可以將Delay添加到行這Binding

MSDN特別提出Slider作爲一個很好的候選人使用它:

如果使用數據綁定來更新數據源,可以使用 延遲屬性指定的時間量來傳遞在源更新之前在目標上更改屬性 之後。例如,假設 您有一個Slider,它的Value屬性數據雙向綁定到 到數據對象的屬性,並且UpdateSourceTrigger屬性是 設置爲PropertyChanged。在這個例子中,當用戶移動Slider時,Slider移動的每個像素的源更新。只有當 滑塊的值停止更改時,源對象通常才需要滑塊的值。爲了防止經常更新源 ,使用延遲指定不應更新源 ,直到拇指停止移動後經過一段時間。

它可以像這樣使用:

<TextBlock Text="{Binding Name, Delay=500}"/> 
+0

我需要長時間運行的任務,以便在滑塊變化時儘可能快地運行。 '延遲'只是防止綁定更新,直到滑塊停止移動... –