2009-07-30 32 views
29

Tôi đang làm một ứng dụng đa luồng nhỏ sử dụng ổ cắm TCP không đồng bộ, nhưng tôi sẽ đến điểm: Tôi đang sử dụng sự kiện tùy chỉnh để đọc giá trị từ biểu mẫu và đại biểu được sự kiện sử dụng trả về chuỗi khi kết thúc.Trả lại giá trị từ Sự kiện - có thực tiễn tốt cho điều này không?

Câu hỏi của tôi ở đây là: có đúng không? có thể trả lại các giá trị từ các sự kiện không? Hoặc là có một cách tốt hơn để làm điều này? (như sử dụng một đại biểu đơn giản cho biểu mẫu để đọc các giá trị)

Trả lời

31

Thường khó xử khi trả lại giá trị từ các sự kiện. Trong thực tế, tôi đã tìm thấy nó dễ dàng hơn nhiều để bao gồm một tài sản ghi trên một tập hợp các EventArgs tùy chỉnh được truyền cho sự kiện, và sau đó kiểm tra sau khi sự kiện cháy - tương tự như hủy tài sản của sự kiện WinForms FormClosing.

+8

Bạn có thể vui lòng xây dựng trên' bao gồm thuộc tính có thể ghi trên một tập hợp EventArgs tùy chỉnh được chuyển đến phần sự kiện' không? – Odys

+0

@Odys Tùy chỉnh đối tượng EventArgument. Tạo thuộc tính nơi kết quả trực tiếp. – Crisfole

15

Ví dụ gần nhất tôi có thể nghĩ là sự kiện FormClosing trong WinForms. Nó cho phép biểu mẫu hủy bỏ sự kiện bằng cách đặt thuộc tính eventArgs.Cancel thành true. Để bạn làm một cái gì đó tương tự, bạn sẽ định nghĩa lớp args sự kiện của riêng bạn với giá trị trả về là thuộc tính trên lớp đó. Sau đó vượt qua một đối tượng args sự kiện bất cứ khi nào bạn nâng cao sự kiện. Bất cứ ai nâng cao sự kiện có thể kiểm tra đối tượng args sự kiện cho giá trị trả lại. Những người khác đang nhận sự kiện cũng có thể kiểm tra hoặc thay đổi đối tượng args sự kiện.

Cập nhật: Tôi vừa chạy qua sự kiện AppDomain.AssemblyResolve và dường như là sự kiện trả về giá trị. Có vẻ như bạn chỉ cần khai báo một loại đại biểu trả về một giá trị, và sau đó xác định sự kiện của bạn với loại ủy nhiệm đó. Tuy nhiên, tôi chưa thử tạo ra sự kiện của riêng mình như thế này. Một lợi thế khi sử dụng thuộc tính trên đối số sự kiện là tất cả người đăng ký tham dự sự kiện đều có thể xem những người đăng ký trước đó đã trở lại.

+1

Lưu ý: bạn có thể sử dụng bất kỳ đại biểu nào để xác định sự kiện, vì vậy cũng sẽ ổn khi xác định một sự kiện như 'chuỗi sự kiện công cộng Func SomeEvent; ', có thể gọi là' bool r = SomeEvent ("foo", "bar"); ' –

26

Tôi không nghĩ rằng đó là một ý tưởng hay ... các sự kiện về cơ bản là các đại biểu đa phương tiện, vì vậy có thể có nhiều trình xử lý. Bạn sẽ nhận được giá trị trả lại nào trong trường hợp đó?

6

Tôi không biết đây có phải là phương pháp hay nhất hay không nhưng tôi đã làm theo cách này.

Func<DataRow, bool> IsDataValid; 

    // some other code .... 

    isValid = true; 
    if (IsDataValid != null) 
    { 
     foreach (Func<DataRow, bool> func in IsDataValid.GetInvocationList()) 
     { 
     isValid &= func(Row); 
     } 
    } 
-1
void method() 
{ 
    list<string> strings = new list<string>(); 

    dostuff += stuff; 
    dostuff += stuff; 

    dostuff(this, new EventHandlerArgs(){ Parameter = strings }) 

    foreach(string currString in strings) 
    { 
      //.... 
    } 
} 

void stuff(object sender, EventHandlerArgs e) 
{ 
    list<string> strings = e.Parameter as list<string>; 

    if (strings != null) 
    { 
     strings.Add(MyString) 
    } 
} 
+2

Chào mừng bạn đến với stackoverflow! Tốt hơn hết là cung cấp mô tả ngắn cho mã mẫu để cải thiện độ chính xác của bài đăng :) –

10

Tôi biết đây là lứa tuổi sau khi bài nhưng nghĩ thêm nhận xét với mã để giải thích Dustin Campbell câu trả lời vì nếu ai đó đi qua chủ đề này. Tôi đã xem qua bài đăng này trong khi cố gắng quyết định điều gì sẽ là phương pháp hay nhất và đây là ý nghĩa của câu trả lời.

Tạo riêng sự kiện tùy chỉnh xử lý lớp học của bạn

public class myCustomeEventArgs:EventArgs 
{ 
    public bool DoOverride { get; set; } 
    public string Variable1 { get; private set; } 
    public string Variable2{ get; private set; } 

    public myCustomeEventArgs(string variable1 , string variable2) 
    { 
     DoOverride = false; 
     Variable1 = variable1 ; 
     Variables = variable2 ; 
    } 
} 

Vì vậy, khi bạn tạo đại biểu sự kiện của bạn, bạn sử dụng args sự kiện tạo của bạn như thế này.

public delegate void myCustomeEventHandler(object sender, myCustomeEventArgs e); 

Và trong lớp nâng cao sự kiện bạn khai báo sự kiện.

public event myCustomeEventHandler myCustomeEvent; 

Vì vậy, khi bạn kích hoạt sự kiện trong lớp của bạn, lớp học lắng nghe sự kiện bạn có thể chỉ trong phần sự kiện được đặt e.DoOverride = true; vì nó sẽ được tuyên bố trong lớp kích hoạt sự kiện.

cháy sự kiện ví dụ:

if(myCustomeEvent != null) 
{ 
    var eventArgs = new myCustomeEventArgs("Some Variable", "Another Varaible"); 
    myCustomeEvent(this, eventArgs); 
    //Here you can now with the return of the event work with the event args 
    if(eventArgs.DoOverride) 
    { 
     //Do Something 
    } 
} 
+0

Làm thế nào để bạn biết khi nào sự kiện sẽ "trả lại"? –

+4

Sự kiện được chạy trên cùng một chuỗi tăng chúng. Mã chạy 'myCustomeEvent (...)' sẽ truyền điều khiển (chạy trên cùng một luồng) tới tất cả các trình xử lý sự kiện đã đăng ký. Khi tất cả các mã của chúng đã được chạy, thì điều khiển sẽ trở lại hướng dẫn ngay sau khi cuộc gọi đến 'myCusomeEvent (...)'. Nếu không có người đăng ký, hoặc có người đăng ký phát lại sự kiện lên một chuỗi khác, thì tất cả thuộc tính trên 'eventArgs' sẽ có giá trị mặc định của chúng (false cho' bool' và 'null' cho chuỗi). –

6

Lưu ý: chỉ sự kiện cuối cùng mới trả về kết quả.

class Program 
{ 
static event Func<string, bool> TheEvent; 

    static void Main(string[] args) 
    { 
     TheEvent += new Func<string, bool>(Program_TheEvent); 
     TheEvent +=new Func<string,bool>(Program_TheEvent2); 
     TheEvent += new Func<string, bool>(Program_TheEvent3); 
     var r = TheEvent("s"); //r == flase (Program_TheEvent3) 
    } 

    static bool Program_TheEvent(string arg) 
    { 
     return true; 
    } 

    static bool Program_TheEvent2(string arg) 
    { 
     return true; 
    } 

    static bool Program_TheEvent3(string arg) 
    { 
     return false; 
    }   
} 
+0

Cảm ơn. Làm việc cho tôi qua một dịch vụ WCF – harveyt

+1

Cảm ơn! Tôi đã tự hỏi xử lý sự kiện nào sẽ "thắng". –

0

Tôi lặp lại các thuộc tính của EventArgs như thế này và rút ra giá trị X và Y của nó.

riêng void navBarControl1_Click (đối tượng người gửi, EventArgs e) { int _x = 0; int _y = 0;

 Type t = e.GetType(); 
     IList<PropertyInfo> props = new List<PropertyInfo>(t.GetProperties()); 

     foreach (PropertyInfo prop in props) 
     { 
      if (prop.Name == "X") 
      { 
       object propValue = prop.GetValue(e, null); 
       _x = Convert.ToInt32(propValue); 
      } 
      if (prop.Name == "Y") 
      { 
       object propValue = prop.GetValue(e, null); 
       _y = Convert.ToInt32(propValue); 
      } 
     } 
+2

hãy làm rõ hơn câu trả lời của bạn – Mostafiz

Các vấn đề liên quan