C# và các lớp cơ sở
Thread ( luồng )Phần 1
1 thread 1 chuỗi liên tiếp những sự thực thi trong chương trình. trong 1
chương trình C# ,việc thực thi bắt đầu bằng phương thức main() và tiếp tục
cho đến khi kết thúc hàm main().
Cấu trúc này rất hay cho nhng chương trình 1 chuỗi xác định những
nhim vụ liên tiếp . nhưng thường thì 1 chương trình cn làm nhiu công
việc hơn vào cùng một lúc.ví d trong internet explorer khi ta đang tải 1
trang web thì ta nhn nút back hay 1 link nào đó , để làm việc này Internet
Explorer sphi làm ít nhất là 3 việc :
- Lấy dữ liệu đưọc trả về từ internet cùng vi các tập tin đi kèm .
- Thể hiện trang web
- Xem người dùng có nhập để làm thgì khác không
Để đơn giản vấn đề ta giả sử Internet Ecplorer chỉ làm 2 công việc :
- Trình bày trang web
- Xem người dùng có nhập gì không
Để thực hành việc này ta sviết 1 phương thức dùng để lấy và thể hiện trang
web .gisử rằng việc trình bày trang web mất nhiều thời gian ( do phải thi
hành các đon javascript hay các hiu ứng nào đó .. ) .vì thế sau một khoảng
thời gian ngắn khoảng 1/12 giây , phương thức sẽ kiểm tra xem người dùng
nhập gì không .nếu thì s đuơc xlí, nếu không thì việc trình y
trang s được tiếp tục. và sau 1/12 giây việc kim tra s được lặp lại.tuy
nhiên viết phương thức này trất phức tạp do đó ta sẽ dùng kiến trúc event
trong window nghĩa là khi việc nhập xảy ra hthống sẽ thông báo cho ứng
dụng bằng cách đưa ra một event . ta sẽ cp nhật phương thức để cho phép
dùng các event :
Ta s viết 1 bộ xử event để đáp ứng đối với việc nhập của người dùng.
Ta sviết 1 phương thức để ly và trình y dliệu . phương thức y được
thực thi khi ta không làm bất cứ điu gì khác.
Ta hãy xem cách phương thức ly và trình bày trang web m việc : đầu tiên
nó stđịnh thời gian. trong khi đang chạy, máy tính kng thể đáp ng
việc nhập của người dùng . do đó phải chú ý đến việc định thời gian để
gọi phương thức kiểm tra việc nhập của người dùng ,nghĩa phương thức
vừa chạy vừa quan sát thời gian.bên cnh đó còn phi quan m đến việc
lưu trữ trạng thái trước khi gọi phương thức khác để sau khi phương thức
khác thực hiện xong sẽ trả về đúng chỗ đã dng.Vào thời window 3.1
đây thực slà nhng gì phi làm để xử tình huống này. tuy nhiên NT3.1
sau đó là windows 95 đã việc xử đa luồng điều này làm việc giải
quyết vấn đề tiện lợi hơn.
Các ứng dụng với đa luồng
Trong ví dtrên minh hotình hung 1 ng dụng cn làm nhiu hơn 1 ng
việc.vì vậy giải pháp rõ ràng là cho ứng dụng thực thi nhiều luồng. như ta đã
nói ,1luồng đaị diện cho 1 chuỗi liên tiếp các lệnh mà máy tính thực thi . do
đó không có do nào 1 ứng dụng li chỉ có 1 luồng.thực vậy ta thể
nhiều luồng nếu ta muốn. tất cđiu cn là mỗi lần ta tạo 1 luồng thực thi
mới, ta chỉ định 1 phương thức mà thực thi nên bắt đầu với. luồng đầu tiên
trong ng dụng luôn được thực thi trong main() vì đây pơng thức mà
.NET runtime luôn ly để bắt đầu.các luồng sau sẽ được bắt đầu bên trong
ứng dụng.
Công việc này làm như thế nào ?
- Một bộ xử chỉ có thể làm một việc vào một c,nếu một hthống đa
x, theo thuyết có thể có nhiều n một lệnh được thi hành đồng bộ,
mỗi lnh trên một bộ xử lí, tuy nhiên ta chlàm việc trên một bộ xử do đó
các công việc không thể xảy ra cùng c.thực sthì hđiều hành window
làm điều này bng một thủ tục gọi là pre emptive multitasking
- Thtục này nghĩa là window lấy 1 luồng vào trong i tiến trình cho
phép luồng đó chạy 1 khoảng thời gian ngắn .gọi là time slice. khi thi gian
này kế thúc. window ly quyền điều khiển li và lấy 1 luồng khác và li cấp
1 khong thời gian time slice . vì khong thời gian này qngn nên ta
cm tưởng như mọi thứ đều xảy ra cùng lúc.
- Thm ckhi ng dụng ta ch một luồng thì thtục này vẫn đưọc dùng
thnhiều tiến trình khác đang chạy trên hthống mỗi tiến trình cn
các time slice cho mỗi luồng của nó.vì vậy khi ta nhiều cửa sổ trên n
hình mi i đại diện cho một tiến trình khác nhau, ta vn thể nhấn vào
bất kì của sổ nào
đáp ứng ngay lập tức.thực sviệc đáp ng nay không phải ngay lập
tức- xảy ra vào sau khong thời gian time slice của luồng đương thời.vì
thời gia này quá ngn nên ta cm thy như nó đáp ứng ngay lập tức.
Thao tác luồng
Luồng được thao tác bằng cách dùng lp Thread nằm trong namespace
System.Threading . 1 th hiện của luồng đaị diện cho 1 luồng.ta thể tạo
các luồng khác bằng cách khởi tạo 1 đối tượng luồng
Bắt đầu 1 luồng
Giả srằng ta đang viết 1 trình biên tập hình nh đồ hoạ, người dùng yêu
cầu thay đổi độ sâu của màu trong nh. ta bắt đầu khởi tạo 1 đối tượng luồng
như sau :
// entryPoint được khai báo trước là 1 delegate kiểu ThreadStart
Thread depthChangeThread = new Thread(entryPoint);
Đoạn mã trên biểu diễn 1 hàm dựng của Thread 1 thông số chỉ định điểm
nhập của 1 luồng. - đó là phương thức nơi luồng bắt đầu thi hành.trong tình
huống này ta dùng thông sdelegate, 1 delegate đã được định nghĩa trong
System.Threading gi là aThreadStart , chữ kí của nó như sau :
public delegate void ThreadStart();
Thông sta truyền cho hàm dng phải là 1 delegate kiểu này .
Ta bt đầu luồng bằng cách gọi phương thức Thread.Start() , giả sử rằng ta
có phương thức ChangeColorDepth() :
void ChangeColorDepth()
{