2012-12-10 33 views
9

Tôi tạo một ví dụ mẫu để gọi liên kết bằng cách sử dụng WebClient bằng cách sử dụng async và đang chờ phương pháp bây giờ tôi muốn đính kèm hủy bỏ chức năng gọi async cũng. Nhưng tôi không thể nhận mã thông báo CancellationTokenSource và đính kèm DownloadStringTaskAsync vào mã thông báo hủy này. Sau đây là mã của tôi bất cứ ai có thể cho tôi biết làm thế nào để thực hiện điều này.Cách đính kèm CancellationTokenSource vào phương thức DownloadStringTaskAsync và hủy cuộc gọi không đồng bộ?

private async void DoWork() 
     { 
      this.Cursor = Cursors.WaitCursor; 
      Write("DoWork started."); 
      cts = new CancellationTokenSource(); 
      WebClient wc = new WebClient(); 
      string result = await wc.DownloadStringTaskAsync(new Uri("http://gyorgybalassy.wordpress.com")); 

      if (result.Length < 100000) 
      { 
       Write("The result is too small, download started from second URL."); 
       result = await wc.DownloadStringTaskAsync(new Uri("https://www.facebook.com/balassy")); 
      } 
      Write("Download completed. Downloaded bytes: " + result.Length.ToString()); 
      Write("DoWork ended."); 
      this.Cursor = Cursors.Default; 
     } 

     private void btnCancel_Click(object sender, EventArgs e) 
     { 
      Write("Cancellation started."); 
      this.cts.Cancel(); 
      Write("Cancellation ended."); 
     } 

Khi nút Hủy của tôi gọi cts.Cancel cuộc gọi DownloadStringTaskAsync không bị hủy. Tại sao nút hủy không thể hủy cuộc gọi Async?

+0

Bạn không sử dụng 'cái CancellationTokeSource' trong bất kỳ cách nào, làm thế nào là' WebClient' phải biết nó nên hủy bỏ khi bạn không nói với nó rằng ? – svick

+0

Cảm ơn svick đã trả lời của bạn. Nhưng tôi đã cố gắng để vượt qua các mã thông báo như là một tham số của phương pháp DownloadStringTaskAsync nhưng không có quá tải cho phương pháp này hỗ trợ nó. Do đó, tôi không nhận được cách sử dụng mã thông báo Cancellation với phương thức DownloadStringTaskAsync. Bạn có thể gợi ý cho tôi một số cuốn sách hay để đọc tất cả các bản cập nhật mới này trong C# với các khả năng TAP không. –

Trả lời

14

Khả năng không đồng bộ của WebClient predate .Net 4.5, do đó, nó chỉ hỗ trợ the Task-based Asynchronous Pattern một phần. Điều đó bao gồm việc có cơ chế hủy riêng của mình: the CancelAsync() method, hoạt động ngay cả với các phương pháp mới -TaskAsync. Để gọi phương pháp này khi một CancellationToken bị hủy bỏ, bạn có thể sử dụng its Register() method:

cts.Token.Register(wc.CancelAsync); 

Là một thay thế, bạn có thể sử dụng mới HttpClient, như Stephen đề nghị, hỗ trợ đầy đủ TAP, bao gồm CancellationToken s.

3

WebClient không hỗ trợ hủy. Tôi khuyên bạn nên sử dụng một loại mới hơn như HttpClient:

... 
cts = new CancellationTokenSource(); 
string result; 
using (var client = new HttpClient()) 
using (var response = await client.GetAsync("http://gyorgybalassy.wordpress.com", cts.Token)) 
{ 
    result = await response.Content.ReadAsStringAsync(); 
} 

if (result.Length < 100000) 
... 

Phương pháp GetAsync theo mặc định sẽ không hoàn thành cho đến khi nó đọc toàn bộ phản ứng, do đó, dòng await response.Content.ReadAsStringAsync sẽ thực sự hoàn thành đồng bộ.

0

phương pháp mở rộng dựa trên câu trả lời của svick:

public static async Task<string> DownloadStringTaskAsync(this WebClient webClient, string url, CancellationToken cancellationToken) { 
    cancellationToken.Register(webClient.CancelAsync); 
    return await webClient.DownloadStringTaskAsync(url); 
} 

public static async Task<string> DownloadStringTaskAsync(this WebClient webClient, Uri uri, CancellationToken cancellationToken) { 
    cancellationToken.Register(webClient.CancelAsync); 
    return await webClient.DownloadStringTaskAsync(uri); 
} 
Các vấn đề liên quan