2011-02-11 9 views
6

このコード行によってExcelが終了しないのはなぜですか?このコードによってExcelが正常に終了しないのはなぜですか?

Excel.Range range = (Excel.Range)ws.Cells[1,1]; 

キャスティングが原因であれば、このコードで同じ問題が発生しないでしょうか?

Excel.Worksheet ws = (Excel.Worksheet)wb.ActiveSheet; 

私は試しました。しかし、これは動作します。 Excelが終了します。

私はこのコードを使用します。 Excelが終了します。

Excel.Range range = ws.get_Range("A1","A1"); 

違いは何ですか?はい、何百万という "Excelを正しく閉じる"スレッドがあることはわかっています。しかし、これは質問であり、答えではないので、私は他人の質問をするのではなく、新しい質問をすることにしました。

ここに私のコードです。もちろん間には別のコードがあります。私はすべてをコメントアウトしていて、どのラインがExcelを終了させないかをゆっくりと試しています。私はガベージコレクタを使わなくても、Excelはまだ閉じていることに気づきます。私はExcelを終了するために大槌を使いたくない。

ありがとうございました。

Excel.Application objExcel = new Excel.Application(); 
Excel.Workbooks wbs = objExcel.Workbooks; 
Excel.Workbook wb = wbs.Open(saveFileDialog1.FileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); 
Excel.Worksheet ws = (Excel.Worksheet)wb.ActiveSheet; 
//Excel.Range range = (Excel.Range)ws.Cells[1,1]; 
Excel.Range range = ws.get_Range("A1","A1"); 

FinalReleaseAnyComObject(range); 
FinalReleaseAnyComObject(ws); 
wb.Close(Type.Missing, Type.Missing, Type.Missing); 
FinalReleaseAnyComObject(wb); 
FinalReleaseAnyComObject(wbs); 
objExcel.Quit(); 
FinalReleaseAnyComObject(objExcel); 

現在、私はobjExcel、wbs、wbおよびwsまで試しました。これらの4つのオブジェクトで問題は発生しません。

private static void FinalReleaseAnyComObject(object o) 
{ 
    Marshal.FinalReleaseComObject(o); 
    o = null; 
} 

私は変数も再利用できないことを認識しています。

Excel.Range range = ws.get_Range("A1","G1"); 
range = ws.get_Range("A1", "A1"); 

これにより、Excelも正しく閉じられなくなります。代わりに、これを使用してください。

Excel.Range range = ws.get_Range("A1","G1"); 
FinalReleaseAnyComObject(range); 
range = ws.get_Range("A1", "A1"); 
+0

@user:閉じると、クラッシュするのですか?キャスト操作で意図的にExcelを閉じるべきではないようです。 –

+0

@ p.campbell閉じるとは、Excelを正しく閉じることを意味します。 Excelまたは多分COMオブジェクトは正しく閉じないというよく知られた問題があります。 ie objExcel.quit()を呼び出した後でも、Excelプロセスはタスクマネージャに残ります。 – user607455

答えて

11

表示されない隠れたRangeインターフェイスポインタがあり、Cellsプロパティがそれを返します。次に、そのRangeのデフォルトのItemプロパティを逆参照して、インデクサー式を適用します。別の範囲を取得する。

これは、COMインターフェイスポインタを自分で管理しようとすると、悪いことに悪い考えです。ガベージコレクタをに、常ににしてください。 GC.Collect()とGC.WaitForPendingFinalizers()が本当に必要なときに終了させたい場合は、プログラムをデバッグするときにいつも期待通りに機能しない理由を理解するには、this answerを必ず読んでください。

+0

ガーベジコレクターが高価だと聞きましたか?私はそれを読んでいないので、それについてはあまり確かではありません。 – user607455

+0

これを試してみました。 "Excel.Range range =(Excel.Range)ws.Cells [1,1];"ガベージコレクターとそれは動作します!それはより良いですか?セルまたはget_Range? GCを完全に避けるべきですか? – user607455

+0

美しい説明ハンス。 user607455、いいえ、Hansは、COMオブジェクトをクリーンアップするときにGCを使用する必要があると言っています。それを避けることはできません。より詳細な議論についてはこちらをご覧ください:http://stackoverflow.com/questions/158706/how-to-properly-clean-up-excel-interop-objects-in-c/159419#159419 –

関連する問題