0

我會盡量簡化我的情況,使之更加簡潔明瞭。因此,我正在開發一個WinRT應用程序,用戶在2秒鐘後輸入TextBoxTextChanged事件中的文本時,需要根據用戶文本進行遠程請求以獲取數據。如果收到新請求,如何取消上一個任務?

現在用戶輸入文本並且Web請求已被初始化,但立即用戶寫入另一個術語。所以,我需要取消第一個Web請求並開啓新的請求。

考慮以下爲我的代碼:

private CancellationTokenSource cts; 

public HomePageViewModel() 
{ 
    cts = new CancellationTokenSource(); 
} 

private async void SearchPeopleTextChangedHandler(SearchPeopleTextChangedEventArgs e) 
{ 
    //Cancel previous request before making new one   

    //GetMembers() is using simple HttpClient to PostAsync() and get response 
    var members = await _myService.GetMembers(someId, cts.Token); 

    //other stuff based on members 
} 

我知道CancellationToken在這裏扮演一個角色,但我不能弄清楚如何。

回答

3

你已經幾乎得到了它。其核心思想是,一個單一的CancellationTokenSource只能一次取消,因此一個新的對每個操作創建。

private CancellationTokenSource cts; 

private async void SearchPeopleTextChangedHandler(SearchPeopleTextChangedEventArgs e) 
{ 
    // If there's a previous request, cancel it. 
    if (cts != null) 
    cts.Cancel(); 

    // Create a CTS for this request. 
    cts = new CancellationTokenSource(); 

    try 
    { 
    var members = await _myService.GetMembers(someId, cts.Token); 

    //other stuff based on members 
    } 
    catch (OperationCanceledException) 
    { 
    // This happens if this operation was cancelled. 
    } 
} 
0

我將實現GetMembers方法是這樣的:

private async Task<List<Member>> GetMembers(int id, CancellationToken token) 
    { 
     try 
     { 
      token.ThrowIfCancellationRequested(); 
      HttpResponseMessage response = null; 

      using (HttpClient client = new HttpClient()) 
      { 
       response = await client.PostAsync(new Uri("http://apiendpoint"), content) 
             .AsTask(token); 
      } 

      token.ThrowIfCancellationRequested(); 
      // Parse response and return result 
     } 
     catch (OperationCanceledException ocex) 
     { 
      return null; 
     } 
    } 

剩下的就是調用cts.Cancel()方法和處理程序每​​次調用GetMembers之前創建的CancellationTokenSource一個新的實例。當然,正如@Russell Hickey所說的,cts應該是全球性的。 (甚至在這個類有多個實例時也是靜態的,並且當調用這個處理函數時你總是想取消方法。通常我也有一個包裝結果的類,並且有一個附加屬性IsSuccessful來區分真實的null結果失敗的操作。

相關問題