2012-03-08 3 views
4

등록 된 이벤트 대리자를 처리하는 순서 또는 우선 순위를 지정하는 방법이 있습니까? 예를 들어 다른 이벤트가 발생하기 직전에 처리하고 싶은 이벤트가 있지만 다른 객체도 이벤트에 대한 리스너를 등록하도록 허용합니다. 이것이 어떻게 성취 될 수 있는가?이벤트 우선 순위 및 프로세스 순서

은 내가 UDP 스트림을 통해 메시지를 전송하는 서버를 가지고, 내가 PROC1 항상이 일을 위해 2

class MessageProcessor 
{ 
    private DataClient Client; 
    public MessageProcesser(DataClient dc) 
    { 
     Client = dc; 
     Client.MessageReceived += ProcessMessage; 
    } 

    void proc1(MessageEventArgs e) 
    { 
     // Process Message 
    } 

} 

class DataClient 
{ 
    public event MessageReceievedHandler MessageReceived; 
} 

void main() 
{ 
    DataClient dc = new DataClient(); 
    MessageProcessor syncProcessor = new MessageProcessor(dc); // This one is high priority and needs to process all sync immediately when they arrive before any data messages 
    MessageProcessor dataProcessor= new MessageProcessor(dc); // This one can process the data as it has time when sync messages are not being processed. 

    // do other stuff 

} 

PROC 전에 그 이유를 실행하려면 말할 수 있습니다. 그것은 데이터 버스트 전에 동기화 메시지를 보냅니다. 동기화 메시지가 수신 될 때 두 핸들러가 실행되지만, 대기 시간을 줄이기 위해 syncProcessor 객체 이벤트를 dataProcessor 이벤트 전에 처리하고 싶습니다. 이렇게하면 처리중인 동기화 메시지의 대기 시간이 줄어 듭니다.

또한 내 팀원이 특정 메시지를 처리하기 위해 이벤트를 등록 할 수도 있습니다. 그들은 이벤트를 등록 할 자신 만의 객체를 가질 수 있습니다 (MessageProcessor가 아닐 수도 있습니다). 심지어 동기화 메시지의 대기 시간은 가능한 한 짧아야합니다.

편집 더 나은 예를 들어 목표를 명확하게했습니다.

+0

처리기에서 MessageEventArgs를 대기열에 넣은 다음 우선 순위 및 의존성을 구현하는 방법을 시작합니다.이 실수를 너무 자주하지 않으려 고 노력하기 전에 당신이 알고있는 버그 퍼스트, 나 자신과 열띤 대화가 있었을 것입니다. –

+0

이 예제에서 같은 리소스/객체 내에 두 이벤트를 모두 등록하는 것이 무의미하다는 것을 깨달았을 때 나는 단순함을 위해 예제를 넣었다. 내 목표를보다 정확하게 표현하기 위해 설정을 변경하겠습니다. – galford13x

+0

@ 토니 : 재미있는 아이디어. 나는 이것이 문제의 영역에 들어갈 수 있다는 데 동의한다. 실제로 누군가가 이벤트를 등록 할 때 인터페이스를 작성하려고 할 때 DataClient가이를 등록했지만 메시지를 수신하면 정의 된 순서로 핸들러의 이벤트를 호출하는 우선 순위 맵핑 오브젝트가 있습니다. 그러나 이것 역시 내려가는 나쁜 길과 같았습니다. – galford13x

답변

0

나는 사지에 나가서 아무 말도하지 않을 것입니다. AFAIK 행사는 본질적으로 무차별 파견됩니다. 그래서 그것은 그것이 묶인 순서대로 파견 될 것입니다. 결과는 다른 순서로 반환 될 수 있습니다. 유일한 방법은 첫 번째 이벤트에 대한 콜백 내에 두 번째 이벤트를 전달하는 것입니다. 이것은 특정 언어가 아니며 이벤트의 아키텍처에 관한 것입니다.

호출이 유효하지 않으므로 예제에서 proc1의 끝에서 proc2를 실행하지 마십시오. 이것은 당신이 다음 가장 좋은 방법은 그것을 확장 할 수 있습니다, 정의 된 자신의 이벤트의 경우이 경우

+1

이벤트가 비동기 적으로 전달됩니까? 나는 그들이 모두 동기로 만드는 동일한 스레드에 모두 파견 된 것이라고 생각했습니다. 정의 된 순서대로 파견된다는 뜻인가요? 그들이 항상 묶여있는 순서대로 파견된다면 가장 우선 순위가 높은 사건이 먼저 등록되도록함으로써 목표를 달성 할 수 있습니까? – galford13x

+0

이벤트가 전달되면 전체 스레드가 잠자기 상태가된다는 말? 이벤트에 아무 것도 묶이지 않으면 어떻게 될까요? 앱이 무기한 대기합니다. 그래서 나는 비동기라고 생각한다. 아니? –

+0

당신이 syncronously 일어날 필요가있는 경우에 기능 1이 사건 처리자 인 기능 1에서 기능 2를 부르십시오. 그렇지 않으면 경쟁 조건이 생성됩니다. 이것은 세계의 모든 다른 이벤트 모델이 존재하는 방식입니다. 나는 C에서 어떻게 작동하는지 99 % 긍정적이다 # –

1

, 당신은 등,

0

오프 단순히 첫 번째 이벤트의 끝에서 두 번째 이벤트를 호출 더 나은 BeforeMessageReceived, MessageReceived 및 AfterMessageReceived 이벤트를 갖습니다. (아마도 메시지가 수신되기 전에 전에 을 알 수 있으므로 MessageProcessed가 더 좋은 루트가 될 수 있습니다.)

이렇게하면 다른 이벤트 처리기가 발생하는 위치를 정확하게 제어 할 수 있습니다.

당신은 볼 같은 이벤트, 사방에 귀갑 후, 전에.

5

이벤트를 여러 번 구독 할 때 이벤트가 발생하면 처리기의 실행 순서를 확인할 수있는 방법이 없습니다.

this answer에 따르면 구독 신청서의 순서는 게시물 작성자의 말처럼 구현 세부 사항이므로 사용자는 이에 의존해서는 안됩니다.

알려진 순서대로 처리기를 실행하는 자신 만의 "이벤트 관리자"(아래 더티 예제 참조)를 작성할 수도 있지만 좋은 생각이라고 생각하지 않습니다. 아마 귀하의 요구 사항을 제거하기 위해 이벤트를 다시 디자인해야합니다.

public class MyClass 
{  
    // Could be anything... 
    public delegate void MyEventHandler(object sender, EventArgs e); 

    public event MyEventHandler TestEvent; 

    public void Test() 
    { 
     if (this.TestEvent != null) 
     { 
      this.TestEvent(this, EventArgs.Empty); 
     } 
    } 
} 

public class EventManager 
{ 
    private List<EventHandler> Handlers = new List<EventHandler>(); 

    public void AddHandler(EventHandler handler) 
    { 
     this.Handlers.Add(handler); 
    } 

    public void RemoveHandler(EventHandler handler) 
    { 
     this.Handlers.Remove(handler); 
    } 

    public void Handler(object sender, EventArgs e) 
    { 
     foreach (var z in this.Handlers) 
     { 
      z.Invoke(sender, e); 
     } 
    } 
} 

private static void Main(string[] args) 
{ 
    MyClass test = new MyClass(); 

    EventManager eventManager = new EventManager(); 

    // Subscribes to the event 
    test.TestEvent += eventManager.Handler; 

    // Adds two handlers in a known order 
    eventManager.AddHandler(Handler1); 
    eventManager.AddHandler(Handler2); 

    test.Test(); 

    Console.ReadKey(); 
} 

private static void Handler1(object sender, EventArgs e) 
{ 
    Console.WriteLine("1"); 
} 

private static void Handler2(object sender, EventArgs e) 
{ 
    Console.WriteLine("2"); 
} 
+0

+1 :이 예는 내가 계획 한 것과 유사합니다. 그러나 나는 너무 나쁜 길로 생각했다. 나는 .net에 내장 된 솔루션을 목표로 삼았다. – galford13x