Bài viết mới

[C#] Hướng dẫn lập trình đa luồng sử dụng Task

[C#] Hướng dẫn lập trình đa luồng sử dụng Task
Đăng bởi: Thảo meo - Lượt xem: 548 09:51:36, 20/05/2020PHẦN MỀM

Trong phiên bản .NET framework 4.0, Microsoft đã bổ sung nhiều thư viện hỗ trợ việc xử lý đa luồng (multi-threading), nhằm đơn giản hóa việc lập trình lẫn hiệu suất của chương trình.

[C#] Hướng dẫn lập trình đa luồng sử dụng Task

Trong bài viết này, tôi xin hướng dẫn các bạn sử dụng lớp System.Threading.Task.

Task

Một Task đại diện cho một số công việc cần phải hoàn thành. Các công việc này có thể chạy trong 1 thread riêng hoặc có thể thực thi một cách đồng bộ, và kết quả được chờ đợi trả về ở thread gọi nó.
Task là một lớp trừu tượng, bạn có nhiều kiểm soát hơn là việc sử dụng Thread.
Task cho phép bạn tổ chức công việc một cách linh hoạt. Ví dụ:
  • Định nghĩa các công việc tiếp theo, được làm sau khi 1 task khác kết thúc. Công việc có thể khác khi công việc trước đó thực thi thành công hay thất bại.
  • Nhận được kết quả trả từ một luồng khác.
  • Kiểm soát lỗi tốt hơn.
  • Dễ dàng chờ đợi 1 hay nhiều Task thực thi xong.
 

Tạo một Task (công việc)

Để tạo 1 Task mà không cần nhận lại kết quả:
 
Cách 1:
Task.Factory.StartNew(() => DoSomeWork); 

Cách 2:

var action = new Action(DoSomeWork);
var task = new Task(action);
task.Start();

Thực hiện Task liên tiếp

Với Task, bạn có thể chỉ ra 1 công việc thực hiện sau khi một công việc khác hoàn thành (tương tự như Background Worker)
static void Example2()
{
    var t1 = new Task(DoOnFirst);
    var t2 = t1.ContinueWith(DoOnSecond);
    t1.Start();
}

static void DoOnFirst()
{
    Console.WriteLine("doing some task {0}", Task.CurrentId);
    Thread.Sleep(3000);
}

static void DoOnSecond(Task t)
{
    Console.WriteLine("task {0} finished", t.Id);
    Console.WriteLine("this task id {0}", Task.CurrentId);
    Console.WriteLine("do some cleanup");
    Thread.Sleep(3000);
}
Với TaskContinuationOptions, bạn chỉ ra điều kiện để thực hiện công việc tiếp theo khi công việc trước đó hoàn thành.
Trong ví dụ dưới đây, Task 3 sẽ thực hiện trong trường hợp Task 2 bị lỗi (throw new exception).
static void Example3()
{
    var t1 = new Task(DoOnFirst);
    var t2 = t1.ContinueWith(DoOnSecond);
    var t3 = t2.ContinueWith(DoOnThird, TaskContinuationOptions.OnlyOnFaulted);
    t1.Start();
}

static void DoOnSecond(Task t)
{
    Console.WriteLine("task {0} finished", t.Id);
    Console.WriteLine("this task id {0}", Task.CurrentId);
    Console.WriteLine("do some cleanup");
    Thread.Sleep(3000);
    throw new Exception("Failed");
}

static  void DoOnThird(Task t)
{
    Console.WriteLine("task {0} failed", t.Id);
    Console.WriteLine("this task id {0}", Task.CurrentId);
}

Nhận kết quả trả về từ Task

Để nhận được kết quả trả về từ Task, bạn sử dụng class Task với T là kiểu dữ liệu của kết quả trả về.
Dưới đây là 3 cách gọi hàm:
static void Example41()
{
    var task = Task.Factory.StartNew(delegate
    {
        DoSomeWork();
        return 2712;
    });
    Console.WriteLine(task.Result);
}

static void Example42()
{
    var task = Task.Factory.StartNew((Func<int>)DoSomeWork1);
    Console.WriteLine(task.Result);
}

static void Example43()
{
    var task = Task<int>.Factory.StartNew(DoSomeWork1);
    Console.WriteLine(task.Result);
}

static int DoSomeWork1()
{
    DoSomeWork();
    return 2712;
}
Lưu ý: TResult property sẽ khóa luồng gọi Task cho đến khi Task đó thực hiện xong.

Chờ đợi 1 (hoặc nhiều) Task

Để chờ đợi 1 Task hoàn thành, bạn gọi hàm Task.Wait
static void Example51()
{
    var task = Task.Factory.StartNew(()=>
    {
        DoSomeWork();
        Console.WriteLine("Complete");
    });
    task.Wait();
}

Để chờ đợi nhiều Task thực thi xong, bạn gọi hàm Task.WaitAll(Task[]).

static void Example52()
{
    var task1 = Task.Factory.StartNew(DoSomeWork);

    var task2 = Task.Factory.StartNew(DoSomeWork);

    Task.WaitAll(task1, task2);
}

Kết luận:

Hi vọng với bài viết nhỏ này, bạn nắm được các cách cơ bản để thực thi 1 công việc đa luồng và kiểm soát chúng tốt hơn.
 
Thanks for watching!
 
 
Theo ngogiaphuc.blogspot.com
 
Tags: task c#

THÔNG TIN TÁC GIẢ

BÀI VIẾT LIÊN QUAN

[C#] Hướng dẫn lập trình đa luồng sử dụng Task
Đăng bởi: Thảo meo - Lượt xem: 548 09:51:36, 20/05/2020PHẦN MỀM