Luồng chính chạy đồng bộ sẽ in ra ba dòng theo thứ tự
internal class ChuongTrinh
{
static void GiaiDoanChinh(string[] thamSo)
{
Console.WriteLine($"1 Luồng chính bắt đầu");
Console.WriteLine($"2 Luồng chính đang làm việc");
Console.WriteLine($"3 Luồng chính kết thúc");
}
}
In ra 1-2-3 liên tiếp chứng tỏ quá trình là đồng bộ
Luồng con sinh ra từ luồng chính mặc định là luồng tiền cảnh không làm chậm luồng chính
internal class ChuongTrinh
{
static void GiaiDoanChinh(string[] thamSo)
{
Console.WriteLine($"1 Luồng chính bắt đầu");
Thread luongCon = new Thread(() => {
Console.WriteLine($"2 Luồng con đang làm việc");
});
luongCon.Start();
Console.WriteLine($"3 Luồng chính kết thúc");
}
}
Có thể thấy luồng con không làm chậm luồng chính
Để in ra theo thứ tự thì phải sử dụng Join hoặc Sleep. Dưới đây là ví dụ với Join
static void GiaiDoanChinh(string[] thamSo)
{
Console.WriteLine($"1 Luồng chính bắt đầu");
Thread luongCon = new Thread(() => {
Console.WriteLine($"2 Luồng con đang làm việc");
});
luongCon.Start();
<strong>luongCon.Join();</strong>
Console.WriteLine($"3 Luồng chính kết thúc");
}
Join buộc luồng chính đợi luồng con hoàn thành trước khi tiếp tục
Ví dụ với Sleep 1 giây để làm chậm luồng chính
internal class ChuongTrinh
{
static void GiaiDoanChinh(string[] thamSo)
{
Console.WriteLine($"1 Luồng chính bắt đầu");
Thread luongCon = new Thread(() => {
Console.WriteLine($"2 Luồng con đang làm việc");
});
luongCon.Start();
//luongCon.Join();
<strong>Thread.Sleep(1000);</strong>
Console.WriteLine($"3 Luồng chính kết thúc");
}
}
Nếu Sleep nằm trong luồng con
internal class ChuongTrinh
{
static void GiaiDoanChinh(string[] thamSo)
{
Console.WriteLine($"1 Luồng chính bắt đầu");
Thread luongCon = new Thread(() => {
<strong> Thread.Sleep(1000);</strong>
Console.WriteLine($"2 Luồng con đang làm việc");
});
luongCon.Start();
//Thread.Sleep(1000);
Console.WriteLine($"3 Luồng chính kết thúc");
}
}
Kết quả không theo thứ tự. Kết luận Sleep làm chậm luồng hiện tại
Với Task trong luồng chính
Task lấy luồng từ pool luồng. Nếu có luồng rảnh sẽ sử dụng, nếu không có sẽ tạo mới
internal class ChuongTrinh
{
static async Task GiaiDoanChinh(string[] thamSo)
{
Console.WriteLine($"1 Luồng chính bắt đầu");
await Task.Run(() =>
{
Console.WriteLine($"2 Task đang làm việc");
});
Console.WriteLine($"3 Luồng chính kết thúc");
}
}
await buộc luồng chính chờ Task hoàn thành
Thử nghiệm await trong luồng con
static async Task GiaiDoanChinh(string[] thamSo)
{
Console.WriteLine($"1 Luồng chính bắt đầu");
Thread luongCon = new Thread(async () =>
{
await Task.Run(() =>
{
Console.WriteLine($"2 Task đang làm việc");
});
await Task.Run(() =>
{
Console.WriteLine($"2.1 Task đang làm việc");
});
await Task.Run(() =>
{
Console.WriteLine($"2.2 Task đang làm việc");
});
});
luongCon.Start();
Console.WriteLine($"3 Luồng chính kết thúc");
}
Chỉ in được đến "2 Task đang làm việc" vì luồng chính kết thúc trước khi các Task còn lại chạy xong
Chuyển Task thành luồng tiền cảnh để đảm bảo in đầy đủ
internal class ChuongTrinh
{
static void GiaiDoanChinh(string[] thamSo)
{
Console.WriteLine($"1 Luồng chính bắt đầu");
Thread luongCon = new Thread(async () =>
{
await Task.Run(() =>
{
<strong> Thread.CurrentThread.IsBackground = false;</strong>
Console.WriteLine($"2 Task đang làm việc, đây là luồng tiền cảnh {Thread.CurrentThread.IsBackground} ");
});
await Task.Run(() =>
{
<strong> Thread.CurrentThread.IsBackground = false;</strong>
Console.WriteLine($"2.1 Task đang làm việc, đây là luồng tiền cảnh {Thread.CurrentThread.IsBackground} ");
});
await Task.Run(() =>
{
<strong> Thread.CurrentThread.IsBackground = false; </strong>
Console.WriteLine($"2.2 Task đang làm việc, đây là luồng tiền cảnh {Thread.CurrentThread.IsBackground} ");
});
});
luongCon.Start();
<strong> Thread.Sleep(1000);</strong>
Console.WriteLine($"3 Luồng chính kết thúc");
}
}
Thiết lập Thread.CurrentThread.IsBackground = false; để Task chạy như luồng tiền cảnh. Thread.Sleep(1000); giữ luồng chính chờ 1 giây để Task có thời gian thực thi hoàn toàn