2016-05-11 6 views
0

構造的な問題があり、結果としてSystem.ObjectDisposedExceptionがdllになります。スレッドDLL呼び出しを使用している間にアプリケーションを終了します

具体的には、カメラからデータをキャプチャすることをお勧めするμEyeCameraドライバです。後者は私のキャプチャが完了しbeeingてて、私は私の画像を保存して続けることができると言われます

  • OnFrameEvent
  • OnSequenceEvent:私は非同期的に解雇され、このカメラからの二つの事象を得ました。

    this?.Invoke((MethodInvoker)delegate() 
    { 
        pbOverallProgress.Value++; 
        pbCapture.Value++; 
    }); 
    
    :あなたはInvoke呼び出しは "キャンセル" -Buttonが押されているようbeeingてObjectDisposedExceptionの原因になります期待し得るような - しかし

    private void onSequenceEvent(object sender, EventArgs e) 
    { 
        uEye.Camera Camera = sender as uEye.Camera; 
        SequenceCount++; 
    
        Camera.Acquisition.Stop(); 
    
        int s32SeqID; 
        statusRet = Camera.Memory.Sequence.GetLast(out s32SeqID); 
    
        Invoke((MethodInvoker)delegate() 
        { 
         lblStatus.Text = "Save Images..."; 
         this.pbCapture.Value = 0; 
        }); 
    
        Rectangle src = new Rectangle(); 
        Rectangle dst = new Rectangle();   
    
        src.X = AOI_Size.X; 
        src.Y = AOI_Size.Y; 
        src.Width = AOI_Size.Width; 
        src.Height = AOI_Size.Height; 
    
        dst.X = 0; dst.Y = 0; dst.Width = AOI_Size.Width; dst.Height = AOI_Size.Height; 
    
        Bitmap bitmap_source = new Bitmap(MySensorInfo.MaxSize.Width, MySensorInfo.MaxSize.Height);; 
        Bitmap bitmap_destination = new Bitmap(dst.Width, dst.Height);; 
    
        Graphics g = Graphics.FromImage(bitmap_destination); 
    
        for (int i = 1; i < s32SeqID; i++) 
        { 
         Camera.Memory.ToBitmap(i, out bitmap_source); 
    
         g.DrawImage(bitmap_source, dst, src, GraphicsUnit.Pixel); 
    
         bitmap_destination.Save(PathToSave + i.ToString() + ".bmp"); 
    
         this?.Invoke((MethodInvoker)delegate() 
         { 
          pbOverallProgress.Value++; 
          pbCapture.Value++; 
         }); 
    
        } 
    
        bitmap_source.Dispose(); 
        g.Dispose(); 
    
        this.CloseForm?.Invoke(1); 
    } 
    

    この

    は、作業を行うコードであります

    キャンセルボタンのコードは次のとおりです。

    private void btn_Exit_Click(object sender, EventArgs e) 
    { 
        if (MessageBox.Show("Do you really want to cancel?", "Abort", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) 
        { 
         this.CloseForm?.Invoke(0); 
        } 
    } 
    
    private void UEye_Dialog_Form_CloseForm(int exitCode) 
    { 
        this?.Invoke((MethodInvoker)delegate() 
        { 
         if (Camera != null) 
         { 
          Camera.EventFrame -= onFrameEvent; 
          Camera.EventSequence -= onSequenceEvent; 
         } 
    
         Camera?.Acquisition.Stop(); 
    
         Camera = null; 
    
         ReturnCode = exitCode; 
    
         this.Close(); 
        }); 
    } 
    

    UEye_Dialog_Form_CloseForm(int exitCode)はイベントで、CloseFormが代理人です。

    私は、これはあまりにも多くの情報ではなかった願っています:)

    この例外私が撮影するシーケンスを待っている場合、画像は、保存されませんbeeingている場合にのみoccure。

    確かに、UI更新コードをtry-catchブロック内にパックするか、フォームの状態がDisposed/Disposingであるかどうかを確認できます。しかし、私の小さなプログラミングスキルのためには、構造的な問題のように見えます。

    はあなたの助けをありがとう:)

答えて

1

トリッキーな部分は、あなたが同期せずにマルチスレッドをやっているということです。

Invokeは、そのような同期ポイントを1つ提示します。これは問題ありません。しかし、あなたが知ったように、ハンドルが破棄された後は機能しません。これは完璧な意味を持ちます。 Invokeは、指定されたハンドルにウィンドウメッセージを送信するだけで、ハンドルがなくなると、メッセージが処理されません(ウィンドウがなくなったときにClose(ちょうどWM_CLOSEなどを送信する)は何もしません)。

これを解決することは、実際は非常に難しいことです。 Invokeを試す前にフォームが処分されているかどうかをチェックしても、チェックとInvokeの間に依然として配置されている可能性があります。 lockは同期を処理できますが、lockは、またはおそらくClosingのようなイベントにする必要があります。重要なのは、送信する信号が安全であることを確認することです。Invokeは現在安全です。もちろん、Invokeを使用する必要はありません。BeginInvokeが必要です。そうしないと、現在ロックが解除されるのを待っているUIスレッドがInvokeで待機する必要がある場合にデッドロックが発生することがあります。いいえ:)

ObjectDisposedExceptionの準備が最適なソリューションかもしれません。しかし、リファレンスソースコードを見れば、100%正しいとは言えません。つまり、1つのスレッドで一貫していますが、UIスレッド(明らかに)にInvokeを呼び出していません。

+0

こんにちはLuaan、あなたの答えに感謝します。実際には 'btn_Exit_Click'のほかに、私が使用しているDLLによって作成された別のスレッドでコードが実行されます。 – AllDayPiano

+1

@AllDayPianoちょうどポイントである 'Invoke'd部分を除いて。 'Invoke'を行う前にウィンドウがスレッドセーフな方法で存在していることを確認する必要があります。これはあなたが現在行っているスレッドとUIスレッドとの同期が必要です。 – Luaan

+0

Ahhhh ok。私はそれについて考えるとかなり明確です!私は、これをどのように解決するかについての良いインプットがあるかもしれないと思います。しかし、あなたの助けに感謝します。これは素晴らしいヒントです! – AllDayPiano

関連する問題