2009-07-11 3 views
1

원래 네이티브 코드로 작성되었으며 .net interops로 래핑 된 API를 사용하고 있습니다. API는 비동기식으로 작동합니다. 각 작업이 완료되면 이벤트가 발생합니다. 모든 논리가 동기화되어 있으므로 작업을 동기화하고 싶습니다. 나는 EventWaitHandle로 그것을하고있다. 여기 _signal.WaitOne() 라인에 갇혀 코드하나의 com 객체 기반 이벤트 동기화

Stock stock; 

private System.Threading.EventWaitHandle _signal = null; 

public void Sync() 

{ 

     _signal = new System.Threading.EventWaitHandle(false,  
         System.Threading.EventResetMode.AutoReset); 
     MBTradingProvider.Instance.FinnishGetStoch += new 
         EventHandler(Instance_FinnishGetStoch); 
     MBTradingProvider.Instance.GetStockAsync("IBM"); 
     _signal.WaitOne(); 
} 

void Instance_FinnishGetStoch(object sender, EventArgs e) 

{ 

     stock = MBTradingProvider.Instance.CurrentWorkongStock; 
     if (_signal != null) 
      _signal.Set();   
} 

이 코드는, 현재의 thread가 정지하고 아무 일도 할 수있다. 다른 비동기 작업에서 같은 패턴으로 작업했는데 정상적으로 작동합니다. 내가 생각할 수있는 유일한 차이점은 두포가 com 객체를 처리한다는 것입니다. 내가 얻은 효과는 WaitOne 행 다음에 코드가 응답하지 않는다는 것입니다.

누구나 잘못된 생각 일 수 있습니까?

답변

0

이 코드의 한 가지 문제점은 _signal 변수의 할당입니다. 이 변수는 원자 적으로 설정되지만 관련된 모든 스레드간에 반드시 표시되는 것은 아닙니다. Interlocked.Exchange와 같은 메소드를 사용하여 모든 스레드에서 세트가 동시에 표시되도록해야합니다.

System.Threading.EventWaitHandle temp = new System.Threading.EventWaitHandle(false,  
         System.Threading.EventResetMode.AutoReset); 
Interolocked.Exchange(ref _signal, temp); 

왜 자동 응답 이벤트를 직접 사용하지 않습니까?

+0

안녕하세요. 해결책을 얻지 못했습니다. 내가 알기로는 모든 스레드가 내 EventWaitHandle (_signal)을 볼 수있는 것은 아닐 수 있습니다. 이 코드가 로컬 "temp"EventWaitHandle을 사용하는 것이 어떻게 정착하는지 이해할 수 없습니까? 더 자세히 설명해 주시겠습니까? 다른 비동기 작업을 호출 할 때 동일한 코드를 사용 했으므로 제대로 작동합니다. 이 두 가지 경우에 사용되는 비동기 프레임 워크에는 차이가있을 수 있습니까? 감사합니다. . –

0

코드가 괜찮은 것 같습니다. 얻을 완료되면 재고 정보

  • 를 얻기 위해 몇 가지 작업을 수행 할,

    1. 동기화() ThreadA
    2. ThreadB을 만듭니다 GetStockAsync()를 호출에서 실행됩니다

      나는 다음을 가정하고 주식 정보, ThreadB, 하지 ThreadA

    내 거친 생각은, 이벤트 핸들러, Instance_FinnishGetStoch()를 실행합니다 가정 # 3은 비동기 프레임 워크에 맞지 않을 수도 있습니다.

    코드를 비동기 적으로 시도하고 GetStockAsyc()을 실행하는 스레드와 Instance_FinishGetStock() 이벤트 처리기를 실행하는 스레드를 확인하십시오.

    하나의 스레드 만 GetStockAsync() 및 Instance_FinishGetStock()을 수행하는 경우 위의 코드는 _signal.WaitOne()에서 멈 춥니 다.

    예를 들어 Winform에서 Form.BeginInoke (MyDelegate)가 UI 스레드에서 호출되면 MyDelegate는 동일한 UI 스레드에서 실행되지만 아직 비동기 적으로 실행됩니다.

  • +0

    안녕하세요, 재생 해 주셔서 감사합니다. 이 코드를 win 형태로 실행하면 코드를 비동기 적으로 실행하면 정상적으로 작동합니다. 어떤 스레드가 내 비동기 코드를 실행하는지 모르지만 비동기 작업이 실행되는 동안 양식을 조작 할 수 있으므로 UI ​​스레드를 사용하지 않는다고 가정합니다. 실행중인 스레드를 볼 수있는 비주얼 라이저 또는 외부 도구를 찾고 있었으나 찾을 수 없었습니다. 나를 위해 하나를 추천 할 수 있다면 기쁠 것입니다. –

    +0

    나는 이벤트 처리기가 다시 UI 스레드로 마샬링되고 있는지 여부를 묻습니다. Thread.CurrentThread.ManagedThreadId 속성을 사용하여 스레드 ID를 확인할 수 있습니다. UI 스레드 및 이벤트 처리기에서 thead id를 표시하는 대화 상자를 왜 표시하지 않습니까? 이 경우 이벤트 핸들러가 UI 스레드에서 실행되는지 여부를 알 수 있어야합니다. –

    +0

    또한 이벤트 핸들러에 중단 점을 설정할 수 있습니다. 그런 다음 VS 디버거는 VS 디버거 내의 스레드 창에서 이벤트 처리기를 실행하는 스레드를 알려야합니다 (디버그 -> Windows -> 스레드). –