1. Trang chủ
  2. » Công Nghệ Thông Tin

Tài liệu Cơ chế ủy quyền và sự kiện phần cuối docx

15 247 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Tài liệu cơ chế ủy quyền và sự kiện
Định dạng
Số trang 15
Dung lượng 196,24 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

// tạo TimeInfoEventArgs để truyền cho các subscriber TimeInfoEventArgs timeInformation = new TimeInfoEventArgs dt.Hour, dt.Minute, dt.Second; } Và để cảnh báo cho những subscriber bằng

Trang 1

public void Run()

{

for(;;)

{

// ngừng 10 giây Thread.Sleep( 10 );

Trang 2

// lấy thời gian hiện hành System.DateTime dt = System.DateTime.Now;

// nếu giây thay đổi cảnh báo cho subscriber

if ( dt.Second != second) {

// tạo TimeInfoEventArgs để truyền // cho subscriber

TimeInfoEventArgs timeInformation = new TimeInfoEventArgs( dt.Hour, dt.Minute, dt.Second);

// nếu có bất cứ lớp nào đăng ký thì cảnh báo

if ( OnSecondChange != null) {

OnSecondChange( this, timeInformation);

} } // cập nhật trạng thái this.second = dt.Second;

this.minute = dt.Minute;

this.hour = dt.Hour;

}

}

Phương thức Run tạo vòng lặp vô hạn để kiểm tra định kỳ thời gian hệ thống Nếu thời gian thay đổi từ đối tượng Clock hiện hành, thì nó sẽ cảnh báo cho tất cả các subscriber và sau đó cập nhật lại những trạng thái của nó

Bước đầu tiên là ngừng 10 giây:

Thread.Sleep(10);

Ở đây chúng ta sử dụng phương thức tĩnh của lớp Thread từ System.Threading của NET

Sử dụng phương thức Sleep() để kéo dài khoảng cách giữa hai lần thực hiện vòng lặp Sau khi ngừng 10 mili giây, phương thức sẽ kiểm tra thời gian hiện hành:

System.DateTime dt = System.DateTime.Now;

Cứ khoảng 100 lần kiểm tra, thì một giây sẽ được gia tăng Phương thức ghi nhận sự thay đổi

và cảnh báo đến những subscriber của nó Để làm được điều này, đầu tiên phải tạo ra một đối tượng TimeInfoEventArgs:

if ( dt.Second != second)

{

Trang 3

// tạo TimeInfoEventArgs để truyền cho các subscriber

TimeInfoEventArgs timeInformation =

new TimeInfoEventArgs( dt.Hour, dt.Minute, dt.Second);

}

Và để cảnh báo cho những subscriber bằng cách kích hoạt sự kiện OnSecondChange: // cảnh báo cho các subscriber

if ( OnSecondChange != null)

{

OnSecondChange( this, timeInformation);

}

Nếu một sự kiện không có bất cứ lớp subscriber nào đăng ký thì nó ước lượng giá trị là null Phần kiểm tra bên trên xác định giá trị của sự kiện có phải là null hay không, để đảm bảo rằng

có tồn tại lớp đăng ký nhận sự kiện trước khi gọi sự kiện OnSecondChange

Chúng ta lưu ý rằng OnSecondChange lấy hai tham số: nguồn phát ra sự kiện và đối

tượng dẫn xuất từ lớp EventArgs Ở đây chúng ta có thể thấy rằng tham chiếu this

của lớp clock được truyền bởi vì clock là nguồn phát ra sự kiện Tham số thứ hai là đối tượng TimeInfo- EventArgs được tạo ra ở dòng lệnh bên trên

Một sự kiện được phát ra thì sẽ gọi bất cứ phương thức nào được đăng ký với lớp Clock thông qua delegate, chúng ta sẽ kiểm tra điều này sau

Một khi mà sự kiện được phát ra, chúng ta sẽ cập nhật lại trạng thái của lớp Class:

this.second = dt.Second;

this.minute = dt.Minute;

this.hour = dt.Hour;

Sau cùng là chúng ta xây dựng những lớp có thể đăng ký vào các sự kiện này Chúng ta

sẽ tạo

hai lớp Lớp đầu tiên là lớp DisplayClock Chức năng chính của lớp này không phải là lưu giữ thời gian mà chỉ để hiển thị thời gian hiện hành ra màn hình console Để đơn giản chúng ta

chỉ tạo hai phương thức cho lớp này Phương thức thứ nhất có tên là Subscribe, phương thức chịu trách nhiệm đăng ký một sự kiện OnSecondChange của lớp Clock Phương thức thứ hai được tạo ra là trình xứ lý sự kiện TimeHasChanged:

public class DisplayClock

{

public void Subscrible(Clock theClock)

{

theClock.OnSecondChange +=

new Clock.SecondChangeHandler(TimeHasChanged);

}

Trang 4

public void TimeHasChanged( object theClock, TimeInfoEventArgs ti) {

Console.WriteLine(“Current Time:

{0]:{1}:{2}”, ti.hour.ToString(), ti.minute.ToString(),

ti.Second.ToString());

Trang 5

}

}

Khi phương thức đầu tiên Subscribe được gọi, nó sẽ tạo ra một delegate

SecondChange- Handler mới, và truyền vào phương thức xử lý sự kiện

TimeHasChanged của nó Sau đó nó sẽ đăng ký delegate với sự kiện OnSecondChange của Clock

Lớp thứ hai mà chúng ta tạo cũng sẽ đáp ứng sự kiện này, tên là LogCurrentTime Thông thường lớp này ghi lại sự kiện vào trong tập tin, nhưng với mục đích minh họa của chúng ta, nó sẽ ghi ra màn hình console:

public class LogCurrentTime

{

public void Subscribe(Clock theClock)

{

theClock.OnSecondChange +=

new Clock.SecondChangeHandler(WriteLogEntry);

}

// thông thường phương thức này viết ra file

// nhưng trong minh họa này chúng ta chỉ xuất

// ra màn hình console mà thôi

public void WriteLogEntry( object theClock, TimeInfoEventArgs ti)

{

Console.WriteLine(“Logging to file:

{0}:{1}:{2}”, ti.hour.ToString(), ti.minute.ToString(),

ti.second.ToString());

}

}

Ghi chú rằng những sự kiện được thêm vào bằng cách sử dụng toán tử += Điều này cho phép những sự kiện mới được thêm vào sự kiện OnSecondChange của đối tượng Clock

mà không

có phá hủy bất cứ sự kiện nào đã được đăng ký Khi LogCurrentTime đăng ký một

sự kiện OnSecondChange, chúng ta không muốn việc đăng ký này làm mất đi sự đăng ký của lớp DisplayClock trước đó

Tất cả phần còn lại cần thực hiện là tạo ra một lớp Clock, tạo mộ đối tượng

DisplayClock và bảo nó đăng ký sự kiện Sau đó chúng ta tạo ra một đối tượng

LogCurrentTime và cũng đăng

Trang 6

ký sự kiện tương tự Cuối cùng thì thực thi phương thức Run của Clock Tất cả phần trên được trình bày trong ví ụ 11.4

Ví dụ 11.4: làm việc với những sự kiện

-

namespace Programming_CSharp

Trang 7

{

using System;

using System.Threading;

// lớp lưu giữ thông tin về sự kiện, trong trường hợp

// này nó chỉ lưu giữ những thông tin có giá trị lớp

clock public class TimeInfoEventArgs : EventArgs

{

public TimeInfoEventArgs(int hour, int minute, int second)

{

this.hour = hour;

this.minute = minute;

this.second = second;

}

public readonly int hour;

public readonly int minute;

public readonly int second;

}

// khai báo lớp Clock lớp này sẽ phát ra các sự kiện

public class Clock

{

// khai báo delegate mà các subscriber phải thực thi

public delegate void SecondChangeHandler(object

clock, TimeInfoEventArgs timeInformation);

// sự kiện mà chúng ta đưa ra

public event SecondChangeHandler OnSecondChange;

// thiết lập đồng hồ thực hiện, sẽ phát ra mỗi sự kiện trong mỗi giây public void Run()

{

for(;;)

{

// ngừng 10 giây Thread.Sleep( 10 );

// lấy thời gian hiện hành System.DateTime dt = System.DateTime.Now;

// nếu giây thay đổi cảnh báo cho subscriber

if ( dt.Second != second) {

Trang 8

// tạo TimeInfoEventArgs để truyền

// cho subscriber TimeInfoEventArgs timeInformation = new TimeInfoEventArgs( dt.Hour, dt.Minute, dt.Second); // nếu có bất cứ lớp nào đăng ký thì cảnh báo

if ( OnSecondChange != null) {

OnSecondChange( this, timeInformation);

} } // cập nhật trạng thái this.second = dt.Second;

this.minute = dt.Minute;

this.hour = dt.Hour;

}

}

private int hour;

private int minute;

private int second;

}

// lớp DisplayClock đăng ký sự kiện của clock

// thực thi xử lý sự kiện bằng cách hiện thời gian hiện hành

public class DisplayClock

{

public void Subscrible(Clock theClock)

{

theClock.OnSecondChange +=

new Clock.SecondChangeHandler(TimeHasChanged);

}

public void TimeHasChanged( object theClock, TimeInfoEventArgs ti) {

Console.WriteLine(“Current Time:

{0}:{1}:{2}”, ti.hour.ToString(), ti.minute.ToString(),

ti.second.ToString());

}

Trang 9

}

Trang 10

// lớp đăng ký sự kiện thứ hai public class LogCurrentTime

{

public void Subscribe(Clock theClock)

{

theClock.OnSecondChange +=

new Clock.SecondChangeHandler(WriteLogEntry);

}

// thông thường phương thức này viết ra file

// nhưng trong minh họa này chúng ta chỉ xuất

// ra màn hình console mà thôi

public void WriteLogEntry( object theClock, TimeInfoEventArgs ti)

{

Console.WriteLine(“Logging to file:

{0}:{1}:{2}”, ti.hour.ToString(), ti.minute.ToString(),

ti.second.ToString());

}

}

// lớp Test minh họa sử dụng sự kiện

public class Test

{

public static void Main()

{

// tạo ra đối tượng clock

Clock theClock = new Clock();

// tạo đối tượng DisplayClock đăng ký

// sự kiện và xử lý sự kiện

DisplayClock dc = new DisplayClock();

dc.Subscribe(theClock);

// tạo đối tượng LogCurrent và yêu cầu đăng

// ký và xử lý sự kiện

LogCurrentTime lct = new LogCurrentTime();

lct.Subscribe(theClock);

// bắt đầu thực hiện vòng lặp và phát sinh sự kiện

// trong mỗi giây đồng hồ

theClock.Run();

} }

}

Trang 11

-

Kết quả thực hiện có

thể như sau:

Current Time: 11:54:20

Logging to file: 11:54:20

Current Time: 11:54:21

Logging to file: 11:54:21

Current Time: 11:54:22

Logging to file: 11:54:22

-

Điều quan trọng chính

của ví dụ minh họa trên là

việc tạo ra hai lớp đối

tượng DisplayClock

và lớp LogCurrentTime

Cả hai lớp này đều đăng

ký một sự kiện

Clock.OnSecondChange

của lớp thứ ba là lớp

Clock

Lợi ích của cơ chế

publish/subscribe là bất

cứ lớp nào cũng có thể

được cảnh báo khi một

sự kiện xuất hiện

Những lớp subscriber

không cần biết cách mà

Clock làm việc, và

Clock cũng không cần

biết cách mà các lớp

subscriber đáp ứng với

sự kiện mà nó đưa ra

Publisher và subscriber

được phân tách bởi deleg ate, đây là một

sự mong đợi cao,

nó làm cho

mã lện

h lin

h họ

at

và mạ

nh

mẽ hơ

n Lớ

p Cl oc

k

có thể tha

y đổi các

h

Trang 12

dò thời gian mà không

làm ảnh hưởng đến bất

cứ lớp subscriber nào

Các lớp subscriber có

thể thay đổi cách mà

chúng đáp ứng với sự

thay đổi của thời gian

mà không tác động với

Clock Cả hai lớp này

hoạt động độc lập với

nhau, và làm cho đoạn

chương trình dễ duy trì

hơn

Câu hỏi và trả lời

Câuhỏi 1: Tóm tắt những

nét cơ bản về uỷ quyền?

Trả lời 1: Ủy quyền là

một kiểu dữ liệu tham

chiếu đươc dùng để

đóng gói phương thức

với các tham số và kiểu

trả về xác định Ủy

quyền cũng tương tự

như con trỏ hàm trong

ngôn ngữ C++ Tuy

nhiên, trong ngôn ngữ

C# ủy quyền là kiểu dữ

liệu hướng đối tượng,

an toàn

và bảo mật

Câuhỏi 2: Con trỏ hàm là

gì?

Trả lời 2: Trong ngôn ngữ

như C hay C++, có một

chức năng gọi là con trỏ

hàm Một con

trỏ hàm được sử dụng

để thiết lập cùng một

nhi

ệm

vụ nh

ư mộ

t

ủy qu yề

n Tu

y nhi

ên, co

n trỏ hà

m tro

ng C/ C + + đơ

n giả

n kh ôn

g ph

ải

là mộ

Trang 13

t đối tượng Còn ủy

quyền trong C# là kiểu

dữ liệu an toàn, được

dùng để tham chiếu đến

những phương thức, ủy

quyền còn được sử

dụng

bởi những sự kiện

Câu hỏi thêm

Câu hỏi 1: Có thể sử dụng

ủy quyền như một thuộc

tính hay không? Nếu có

thể thì sử dụng như thế

nào? Cho biết ý nghĩa?

Câu hỏi 2: Nếu có một số

hoạt động cần được thực

hiện theo một thứ tự nhất

định thì ta phải

làm thế nào để khi cần

thực hiện thì gọi lần lượt

thực hiện các hoạt động

đó?

Câu hỏi 3: Công dụng của

việc khai báo ủy quyền

tĩnh? Khi nào thì nên khai

báo ủy quyền tĩnh khi nào

thì không nên?

Câu hỏi 4: Một ủy quyền có

thể gọi được nhiều hơn

một phương thức hay

không? Chức năng nào

trong C# hỗ trợ ủy quyền

này?

Câu hỏi 5: Có phải tất cả

các ủy quyền đều là ủy

quyền Multicast hay

không? Điều kiện để trở

thành ủy quyền Multicast?

Câu hỏi 6: Các toán

tử nào

có thể dùn

g để thực hiện việc Mul tica

st các

ủy quy ền? C â u h ỏ

i 7 :

S ự

k i ệ n

l à g

Trang 14

ì? Trong hệ thống

ứng dụng nào thì sự

kiện được sử dụng

nhiều?

Câuhỏi 8: Những sự kiện trong C# được

thực hiện thông qua

cái gì?

Câu hỏi 9: Hãy tóm lược quá trình tạo một sự kiện

và giải quyết sự kiện thông qua cơ chế ủy quyền trong C#?

Bài tập

Bài tập 1: Viết chương trình minh họa sử dụng

ủy quyền để thực hiện việc sắp xếp các số

nguyên trong một mảng? Bài tập 2: Viết chương trình minh họa sử dụng ủy quyền để thực hiện việc chuyển các ký tự thường thành ký tự hoa trong một chuỗi?

Bài tập 3: Viết chương trình kết hợp giữa

delegate và sự kiện để minh họa một đồng hồ điện

tử thể hiện giờ hiện hành trên màn hình console

Ngày đăng: 26/01/2014, 03:20

TỪ KHÓA LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w