2009-09-07 1 views
1

내 프로젝트에 개체를 데이터베이스에 저장하는 코드가 있습니다.이 코드를 완료하면 일련의 다른 메서드를 호출해야합니다.C# 대리자 및 이벤트 디자인 도움말

다른 방법으로이 이벤트를 구독 할 수 있도록 허용하고 싶습니다. 그래서 필요한만큼 추가 할 수 있습니다. 이 방법에 대한 아이디어는 다른 메서드를 등록 할 수있는 대리자 배열을 만드는 것이 었습니다. 개체가 저장되면 대리자를 반복하고 각 개체를 호출 할 수있었습니다.

좋지 않은 행동인가, 아니면 더 좋은 방법이 될 수 있습니까?

감사

답변

1

당신은 많은 대표를 구독 할 수 있습니다 :

이벤트에 가입하는 구문은 단서를 제공합니다. 두건의 밑에 .Net는 어쨌든 주문한 수집으로 이것을 유지한다.

이에 대한 표준 패턴은 다음과 같습니다

//in your class 
public EventHandler<MyEvtArgs> MyEvent; 

protected void OnMyEvent (MyEvtArgs args) { 
    if(MyEvent != null) //make sure there is at least 1 subscriber 
     MyEvent(this, args); 
} 

다음이 전화 :

당신의 OnMyEvent 보호 방법을 발광하는 클래스 안에이 모든 이벤트라고 지금
var myInstance = new MyClass(); 

// all of these can convert to EventHandler<MyEvtArgs> (object, MyEvtArgs) 
myInstance.MyEvent += (sender, e) => { /* do something 1 */ }; 

myInstance.MyEvent += (sender, e) => { /* do something 2 */ }; 

myInstance.MyEvent += localMethod; 

- 위해 .

또한이 컬렉션에서 항목을 제거 할 수 있습니다

myInstance.MyEvent -= localMethod; 
+0

참고로, null 체크를 피하기 위해 잠시 동안 내 처리기를 기본값으로 설정했습니다. 즉, public 이벤트입니다. EventHandler MyEvent = delegate {}; –

+0

네 - 널 검사에 비해 약간의 오버 헤드가 있기 때문에 그렇게하지 않는 것이 좋습니다. 실제로 그 차이는 너무 작아서 코드에서 가장 잘 작동하는 것으로 내려갑니다. – Keith

+0

if (MyEvent! = null) 구문을 사용하면 스레드로부터 안전하지 않으며 경쟁 조건이 발생할 수 있습니다. –

1

당신은 배열을 필요가 없습니다. 누구든지 구독하도록하십시오.

+0

위임자가 아니고 이것이 어떻게 작동하는지 잘 모르겠습니다. "공개 대리자 void Del (문자열 메시지); Del handler = DelegateMethod;와 같은 코드를 사용합니다. 하나 이상의 메소드가이 델리게이트에 등록하는 방법은 무엇입니까? – Gavin

+0

@ PVit 's anwer –

2

이벤트 대리자는 둘 이상의 이벤트 처리 방법에 대한 참조를 보유 할 수 있음을 의미하는 멀티 캐스트입니다. DelegateMulticastDelegate에 대한 MSDN 설명서를 참조하십시오. 단일 이벤트에 원하는

MyEvent += MyHandler; // subscribe to an event 
MyEvent -= MyHandler; // unsubscribe from an event 
0

당신은 이것에 대한 일반적인 이벤트를 사용할 수 있습니다. 런타임은 모든 필드에 대해 루핑을 처리합니다.

public event EventHandler<EventArgs> WritingToDatabaseFinished; 

protected void OnWritingToDatabaseFinished(EventArgs args) 
{ 
    EventHandler<EvetnArgs> handler = WritingToDatabaseFinished; 
    if (handler != null) 
    { 
     handler(this, args); 
    } 
} 

귀하의 코드가

OnWritingToDatabaseFinished(args); 

연락 원하는 모든 메소드를 호출하면 이벤트에 등록해야합니다 :

WritingToDatabaseFinished += new EventHandler<EventArgs>(handlermethod); 

위의 방법으로 등록 된 모든 핸들러가 될 것입니다 OnWritingToDatabaseFinished를 호출 할 때 호출됩니다.

+1

C# 3의 작은 niggle을 사용하면 WritingToDatabaseFinished + handlermethod를 말할 수 있습니다. –

+0

감사합니다. 내가 알지 못했던 멋진 구문 설탕. – PVitt

0

멀티 캐스트 대리인이 필요합니다. 배열이 필요 없습니다. 대리자에 대한 참조를 추가하려면 + =를 사용하고 참조를 제거하려면 - =를 사용합니다.

대신 약한 이벤트 처리기를 사용하는 것이 좋습니다. this link에서 약한 대리인 대신 약한 이벤트를 사용하는 이유를 확인하십시오.

0

대리인은 이미 멀티 캐스트되어 있으므로 대리인 배열이 필요 없습니다.지금, 당신의 클래스에 이벤트 지원을 추가하는 권장되는 방법은 다음과 같습니다

  1. (이 이벤트 핸들러 예정) 공공 대리자를 추가

공공 대리인이 무효 DatabaseEventHandler (개체를 보낸 사람, DatabaseEventArgs 전자);

  1. 대리인 유형의 공개 이벤트를 추가합니다.

public 이벤트 DatabaseEventHandler DatabaseDone;

이제 이벤트는 2 개의 매개 변수를 전송해야합니다. 보낸 사람 (보통) 및 EventArgs System.EventArgs에서 새 클래스를 만들고 해당 클래스 내에서 적절한 정보를 보내야합니다.