sobota, 26 grudnia 2015

Wielowątkowość - Task

Dziś porozmawiamy o wątkach w C#

Klasa Task wymaga zastosowania następującej przestrzeni nazw:

using System.Threading.Tasks;

Jest kilka sposobów tworzenia wątków.. Stwórzmy do tego prostą metodę w Console Aplication:

public static int DoWork( int val )
{
    var tmpVal = 0;
    for ( int i = 0; i < val; i++ ) {
         tmpVal += i;
    }
    return tmpVal;
}

static void Main( string[] args )
{
    //..
}

Przypominam że delegat Action umożliwia przypisanie metody zwracającej void.


1) Pierwszy ze sposobów to Lambda expression :

static void Main( string[] args )
{
     const int taskLoop = 100;
     var task = new Task<int>( () => DoWork( taskLoop ) );
     task.Start();
     Console.WriteLine( task.Result );
}

2) Lub..

static void Main( string[] args )
{
     const int taskLoop = 100;
     var task = new Task<int>( n => DoWork( (int)n ), taskLoop );
     task.Start();
     Console.WriteLine(task.Result);
}

3) Można również zastosować metodę "w locie" umieszczając ją w nawiasach:

static void Main( string[] args )
{
     const int taskLoop = 100;
     var task = new Task<int>( () => {
     var tmpVal = 0;
     for ( int i = 0; i < taskLoop; i++ ) {
         tmpVal += i;
     }
     return tmpVal;
     });
     task.Start();
     Console.WriteLine( task.Result );
}



Ważnym aspektem wątków jest możliwość ich przerwania w czasie wykonywania z poziomu wątku głównego można to powiązać z wyrzuceniem wyjątku:

public static int DoWork(CancellationToken ct,  int val )
{
    var tmpVal = 0;
    for ( int i = 0; i < val; i++ ) {
        tmpVal += i;
        ct.ThrowIfCancellationRequested();
    }
    return tmpVal;
}

static void Main( string[] args )
{
      const int taskLoop = 100;
      CancellationTokenSource cs = new CancellationTokenSource();
      var task = new Task<int>(() => DoWork(cs.Token,1000));
      task.Start();
      cs.Cancel();

      try {
           Console.WriteLine("Wynik to: {0}",task.Result);
      }
      catch ( AggregateException ex ) {
      ex.Handle( e => e is OperationCanceledException );
      Console.WriteLine("Operacja anulowana");
}

Powyższy kod spowoduje zatrzymanie wykonywania wątku już przy pierwszej pętli a to wszytko poprzez argument CancellationTokenSource cs = new CancellationTokenSource(); który po wywołaniu metody Close() powoduje wyrzucenie wyjątku.

 

Brak komentarzy:

Prześlij komentarz