1️⃣ Task
1.1 Task không có kiểu trả về
- Task nhận vào một
Actionkhông có param:
Task t2 = new Task(Action);
- Task nhận vào một
Actioncó param, đối số thứ 2 là giá trị truyền vàoAction:
Task t3 = new Task(Action<object>, object);
- Chờ tất cả task hoàn thành trước khi gọi lệnh tiếp theo:
t2.Wait();
t3.Wait();
Console.WriteLine("Press any key");
- Cách ngắn gọn dùng
Task.WaitAll():
Task.WaitAll(t2, t3);
- Ví dụ chức năng Task:
static Task Task2()
{
Task t2 = new Task(() =>
{
// Do something
});
t2.Start();
t2.Wait();
Console.WriteLine("T2 Finish");
return t2;
}
static Task Task3()
{
Task t3 = new Task(() =>
{
// Do something
});
t3.Start();
t3.Wait();
Console.WriteLine("T3 Finish");
return t3;
}
Task t2 = Task2();
Task t3 = Task3();
💡 Lưu ý: Dù task chạy trên nhiều luồng khác nhau, việc gọi Wait() khiến chương trình thực thi giống đồng bộ.
1.2 Task có kiểu trả về
- Task trả về giá trị string, không có tham số đầu vào:
Task<string> t4 = new Task<string>(() =>
{
// Do something
return "Result from T4";
});
- Task trả về string, có tham số đầu vào:
Task<string> t5 = new Task<string>((object obj) =>
{
string t = (string)obj;
return $"Result from {t}";
}, "T5");
- Thực thi và lấy kết quả:
t4.Start();
t5.Start();
Task.WaitAll(t4, t5);
var resultT4 = t4.Result;
var resultT5 = t5.Result;
Console.WriteLine("Press any key");
- Chuyển thành function con:
static Task<string> Task4()
{
Task<string> t4 = new Task<string>(() =>
{
return "Result from T4";
});
t4.Start();
return t4;
}
static Task<string> Task5()
{
Task<string> t5 = new Task<string>((object obj) =>
{
string t = (string)obj;
return $"Result from {t}";
}, "T5");
t5.Start();
return t5;
}
Task<string> t4 = Task4();
Task<string> t5 = Task5();
Task.WaitAll(t4, t5);
var resultT4 = t4.Result;
var resultT5 = t5.Result;
Console.WriteLine("Press any key");
2️⃣ Từ khóa Async & Await
- Khi dùng
async/await:await t2hayawait t3sẽ đợi task hoàn thành trước khi chạy statement tiếp theo.- Không khóa thread chính, task vẫn chạy trên các luồng riêng, kết quả luân phiên nhau.
2.1 Đối với Task không có kiểu trả về
static async Task Task2()
{
Task t2 = new Task(() =>
{
// Do something
});
await t2;
Console.WriteLine("T2 Finish");
}
static async Task Task3()
{
Task t3 = new Task(() =>
{
// Do something
});
t3.Start();
await t3;
Console.WriteLine("T3 Finish");
}
2.2 Đối với Task có kiểu trả về
static async Task<string> Task4()
{
Task<string> t4 = new Task<string>(() =>
{
// Do something
return "Result from T4";
});
t4.Start();
var result = await t4;
Console.WriteLine("T4 Finish");
return result;
}
static async Task<string> Task5()
{
Task<string> t5 = new Task<string>((object obj) =>
{
string t = (string)obj;
return $"Result from {t}";
}, "T5");
t5.Start();
var result = await t5;
Console.WriteLine("T5 Finish");
return result;
}
// Gọi thực thi
Task<string> t4 = Task4();
Task<string> t5 = Task5();
// Lấy kết quả
var resultT4 = await t4;
var resultT5 = await t5;
Console.WriteLine("Press any key");
💡 Key Point: async + await giúp:
- Chờ task hoàn thành nhưng không block main thread.
- Task chạy độc lập, statement tiếp theo chỉ thực thi khi task hoàn thành.
- Phù hợp cho cả Task có kiểu trả về hoặc không có kiểu trả về.