2016-10-29 3 views
0

나는 ValueGenerated라는 이름의 이벤트가 있습니다. ValueGenerated 값을 생성하고 발생시키는 코드는 스레드에서 실행되며이 이벤트를받는 메소드는 form.control (즉 양식)에 있습니다. UI 스레드가 다른 스레드가 UI를 변경하는 것을 허용하지 않기 때문에 나는 이벤트 세대에서 다음 코드를 작성 :이벤트 타겟을 얻는 방법

if (ValueGenerated.Target is System.windows.form.control) 
{ 
Control targetForm = ValueGenerated.Target as control; 
targetForm.Invoke(ValueChanged,new object[]{this,args}); 
} 

하지만 이벤트가 하나 이상의 메도에 의해 등록 된 경우 무슨 생각합니다. 예를 들어, 두 개 또는 세 개의 목적지. 왜 이벤트와 델리게이트 클래스에는 마지막 메소드의 인스턴스 객체를 반환하는 Target 속성 만 있습니까? 우리는 항상 마지막 것만 필요합니까?

+0

GetInvocationList를 사용하여 모든 가입 된 대리인을 가져옵니다. 그런 다음 모든 대상을 검사하여 대상이 무엇인지 확인할 수 있습니다. –

+0

누가 다른 스레드에서 UI를 업데이트 할 수 없다고합니까? – Jim

+1

이벤트의 실제 백업 저장소는 MulticastDelegate입니다. 여러 명의 가입자를 허용하여 대의원을 확대합니다. 잠재적 스레딩 버그를 숨기는 것은 매우 나쁜 생각입니다. 특히 Invoke()는 교착 상태가 발생하기 쉽기 때문에 이벤트 핸들러 메서드에 반환 값이 없기 때문에 절대로 필요하지 않습니다. 특히 UI에 영향을주는 이벤트는 작업자 스레드가 계속 실행 중이지만 사용자가 창을 닫으면 잘못 될 수 있습니다. 하지 마. –

답변

2

잘못하고 있습니다.

주석에서 언급했듯이 위임 인스턴스에서 GetInvocationList()을 호출하여 호출 대상의 전체 목록을 가져올 수 있습니다. 그런 다음 각 대상을 개별적으로 호출 할 수 있습니다.

그러나 이것은 이 아니며 올바른 방법입니다. 이벤트는 모든 핸들러를 동일하게 취급해야합니다. 이벤트가 백그라운드 스레드에서 제기 항상 인 이벤트의 종류이며,이 항상는 UI 스레드에 파견 적절한 메커니즘을 사용해야 후, 항상 UI의 객체가 취급하는경우

. 이러한 디자인의 예로는 ProgressChangedRunWorkerCompleted 이벤트와 같이 BackgroundWorker 클래스를 참조하십시오.

이러한 조건 중 하나라도 틀린 경우 이벤트는 어떤 방식 으로든 크로스 스레드 호출을 처리하지 않아야합니다. 스레드 선호도가있는 이벤트의 구독자는 해당 이벤트를 처리해야합니다.

불행히도, 그 이상의 구체적인 조언을 제공하기에 충분한 문맥이 질문에 없습니다. 유일한 확실한 점은 막달레나 길을 시작했다는 것입니다. 돌아서 돌아와서 더 부드러운 경로를 선택하십시오. :)

+0

이 솔루션은 괜찮습니다. 하지만 BackgroundWorker의 작업을 구성 요소로 원합니다. 예를 들어, sin (t)와 같은 함수를 100 밀리 초마다 계산하고 함수의 값을 포함하는 이벤트를 발생시키는 구성 요소가 필요합니다. 이 이벤트는 게이지와 같은 그래픽 컨트롤에서 사용자에게 보여줄 수 있습니다. 이 신호 생성기를 폼에 드롭 될 가능성이있는 구성 요소로 갖고 싶습니다. BackgroundWorker에서 확장하는 것이 좋은 생각입니까? – Pat928

+0

예를 들어 두 가지 문제가 있습니다. 1) 장기 실행 작업은 'BackgroundWorker'에 적합하지 않습니다. 왜냐하면 스레드 풀 스레드를 묶어주기 때문입니다. 2) trig 함수를 주기적으로 계산하는 작업은 주기적으로 관계가 없습니다. 스레드 친화적 인 객체에 적용 할 수 없으므로 그러한 구성 요소에 스레드 유사성 기능을 포함하는 것은 부당하고 복잡합니다. 즉,이 예에서 어쩌면 C#'이벤트 '가 어쨌든 그 동작을 표면 처리하는 가장 좋은 방법은 아닐 수도 있습니다. 그것은 루프와'await Task.Delay (100);에 대한 호출을 가진'async' 메소드처럼 보일 것입니다. –

+0

아니, 당신은 그것을 얻지 못했습니다. 값을 생성하는 구성 요소가 필요하며이 구성 요소에이 이벤트를 수신하기 위해 등록하는 리스너가 있습니다 (회로 구성 요소의 신호를 생성하는 클록 펄스 생성기와 유사). 값 생성은 다른 구성 요소에 의해 제어되지 않고 값 호출에 대한 응답으로 얻지 못함 (결과적으로 제안과 같이 비동기) – Pat928

관련 문제