2015-11-22 19 views
7

.NET 4.5.1: CancellationTokenSource yerleşik zaman aşımını kullanarak bir görevin içinde çalışan bir engelleme yöntemini iptal edemiyorum.C#: CancellationToken engelleme yöntemini iptal etmiyor

class Program 
{ 
    static void Main(string[] args) 
    { 
     var cts = new System.Threading.CancellationTokenSource(); 

     System.Console.CancelKeyPress += (s, e) => 
     { 
      e.Cancel = true; 
      cts.Cancel(); 
     }; 

     MainAsync(args, cts.Token).Wait(); 
    } 

    // MainAsync from http://stackoverflow.com/questions/9208921/async-on-main-method-of-console-app 
    static async Task MainAsync(string[] args, System.Threading.CancellationToken token) 
    { 
     Console.WriteLine("Starting MainAsync"); 
     var cts = new System.Threading.CancellationTokenSource(3000); 
     var task = Task.Factory.StartNew(() => 
     { 
      Console.WriteLine("Starting task..."); 
      var t = new System.Net.Sockets.TcpClient(); 
      var buffer = new byte[t.ReceiveBufferSize]; 
      t.Connect(new System.Net.IPEndPoint(System.Net.IPAddress.Parse("127.0.0.1"), 1337)); 

      Console.WriteLine("Recieving..."); 
      t.Client.Receive(buffer); 
      Console.WriteLine("Finished Recieving..."); 

      return true; 
     }, cts.Token); 

     var success = await task; 

     Console.WriteLine("Did the task complete succesfuly?", success); 
    } 
} 

, Doğru Örnek (Ben doğru umut) İçerdiği yukarıdaki Kısa, Öz den çıkış geçerli:

Starting MainAsync 
Starting task... 
Recieving... 

Neden görev iptal etmez gelmez, hiçbir istisnası atılır? Bloguma devlet gibi

+0

Burada kullandığınız gibi socket.receive kullanmak bir engelleme çağrısıdır - zaman aşımı veya zaman uyumsuzluğu kullanmanız gerekir, böylece işleme sırasında iptal yöntemini yeniden değerlendirebilirsiniz. CancellationToken, çağrıları sizin için engellemeyi sonlandırmayacaktır. – Joe

cevap

3

Emin değilim ama sanırım "bir iş parçacığı/görevi sonlandırmak veya iptal etmek" ile "iptal isteğinde bulunmayı" karıştırıyorsunuz. Bunlar iki tamamen farklı şeyler. Canellation in Managerd Threads ile ilgili açıklamaya göre, sağlanan işlev, devam eden işlemin durduğunu belirten bir sinyal gibi bir şey göndermenizi sağlar.

Bu sinyale nasıl tepki verirseniz yanıt verirsiniz - bir programcı olarak - size kalmış. Örnekte

iptal işlemi işlemek ne de bunu yapmak için uygundur olmayan yeni bir görev

var task = Task.Factory.StartNew(() => 
{  
    Console.WriteLine("Starting task..."); 
    var t = new System.Net.Sockets.TcpClient(); 
    var buffer = new byte[t.ReceiveBufferSize]; 
    t.Connect(new System.Net.IPEndPoint(System.Net.IPAddress.Parse("127.0.0.1"), 1337)); 

    Console.WriteLine("Recieving..."); 
    t.Client.Receive(buffer); 
    Console.WriteLine("Finished Recieving..."); 

    return true; 
}, cts.Token); 

başladık. Canellation örn. Bir döngüden çok yineleme ile çıkmak istiyorsanız - bu nedenle, her yinelemede CancellationToken.IsCancellationRequested'un true olarak ayarlanıp ayarlanmadığını kontrol edersiniz. Varsa, buna göre tepki verebilirsiniz.

İstediğiniz şey, geçerli görevlerin ardındaki ipucunu iptal etmektir, ki bu sadece benim için Thread sınıfının yeni bir örneğini oluşturarak mümkündür ve iptal işlemini buna göre halledebilirsiniz.

İlgili konular