質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

1回答

1612閲覧

for文の途中でエラーがでる C#

mi-san

総合スコア14

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2020/05/26 05:39

編集2020/05/26 05:43

前提・実現したいこと

操作しているPC1に制御しているネットワークアナライザ(PC2)にbmp→バイナリに変換したファイルデータを送りたい。

発生している問題・エラーメッセージ

for文を使用して8回繰り返しているのですが、6,7回目でこのエラーがでたり、時々8回成功して終了したりしてます。
inst.IO = rm.Open(ネットワークアナライザのVISAアドレス) as IMessage; ここで

c#

1 2COMEExceptionはハンドルされませんでした。 3HRESULT=8004003c

該当のソースコード

for文は途中まで動いているのでとりあえずfor文の中身です。
cese文を使って繰り返し作業をしようとしてました。

・・・・・ IMessageBasedSession session; // VISA.NET IMessageBasedFormattedIO instrument0; session = (IMessageBasedSession)GlobalResourceManager.Open(ネットワークアナライザのVISAアドレス); ・・・・・ int num2=1,b; string File_Name; for (b = 1; b <= 8; b++) { switch (num2) { case 1: File_Name = sn.Text + "No1"; num1 = 2;           break; case 2:           File_Name = sn.Text + "No2"; num1 = 3; break;           ---case3~7略--- case 8:           File_Name = sn.Text + "No8"; break; } instrument0 = session.FormattedIO; session.TimeoutMilliseconds = 10000; instrument0.WriteLine("INIT1:CONT OFF");        Byte[] bmpDat = GetScreenshot(); Bitmap bmp = Bithenkan(bmpDat);        bmp.save(PC1の保存先のアドレス + ".bmp");       }   public Byte[] GetScreenshot()  //スクリーンの画像をネットワークアナライザに保存、バイナリデータに変換 { Byte[] dat12 = null; FormattedIO488 inst = new FormattedIO488(); ResourceManager rm = new ResourceManager(); inst.IO = rm.Open(ネットワークアナライザのVISAアドレス) as IMessage; inst.IO.Timeout = 10000; inst.WriteString("MMEM:STOR:IMAG " + "'" + "D:\" + File_Name + ".bmp" + "'"); inst.WriteString("MMEM:TRAN? " + "'" + "D:\" + File_Name + ".bmp" + "'"); try { inst.IO.Timeout = 2000; dat12 = inst.ReadIEEEBlock(IEEEBinaryType.BinaryType_UI1) as Byte[]; inst.IO.Close(); } catch { } finally { session.TimeoutMilliseconds = 10000; } return dat12; }   private Bitmap Bithenkan(Byte[] ba2) //バイナリ→bmp画像変換       { Bitmap bmp = null; ImageConverter ic = new ImageConverter(); bmp = new Bitmap(ic.ConvertFrom(ba2) as Image); return bmp; }

試したこと

最後まではいかなくても一応動いているプログラムですし、出来るときとできないときがあるっていう点で
個人的にfor文のせいでPC内部のなんかがおかしくなっていると思って
接続を一旦切ればいいかなと思い
inst.IO.Close();を追加で入れましたが、偶然かわかりませんが5回でエラーが出てたのが6回目までいけるようになりました。

機器との接続法を二種類(IMessageBasedFormattedIOとFormattedIO488)使用しているせいかもしれませんが、
どっちか一つにまとめようとしましたが、お互いにお互いにしかできない仕事ができるので、できれば二種類のままでできる方法が知りたいです。

よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2020/05/26 05:46

inst.IO.Close(); とか session.TimeoutMilliseconds = 10000; の位置がおかしくありませんか? try catch finally の役目を見直してみてください。
mi-san

2020/05/26 05:56

ありがとうございます。 try{エラーがでなかったらやりたいこと} catch{エラーがでたらやること} finally{上の二つのどちらかが終わったらやること}と認識しているのですが違うんでしょうか?
Zuishin

2020/05/26 06:08 編集

たとえば ReadIEEEBlock が例外を発生させた時、その例外を握りつぶして inst.IO をクローズせず戻りますよね? するとつぎに呼んだ時、前の inst.IO が開かれたまま、次のものを新しく開くことになりませんか?
mi-san

2020/05/26 06:14

ありがとうございます。すみません上の試したことにかきわすれていました… catch{     inst.IO.Close();    } も入力してみましたが何も変化がなかったので、意味ないのかなと思い未入力のままにしてました。
Zuishin

2020/05/26 06:15

それだと、例外が発生したときだけクローズするようになります。finally に入れましょう。
Zuishin

2020/05/26 06:17

また、catch ブロックは取り除いてください。例外が握りつぶされて見えないのでは、何のための例外かわかりません。
mi-san

2020/05/26 06:23

ありがとうございます。finally に入れてcatch ブロック削除しましたが、編集直後は8回ループ成功したのですが、3回ほど試しに動かしてみたらまた7回目でエラーがでてしまいました…
Zuishin

2020/05/26 06:26

inst.IO.Close(); の次の行に inst.IO = null; GC.Collect(); を入れるとどうなりますか?
mi-san

2020/05/26 06:33

ありがとうございます。 今10回ほど試してみましたがエラーがでなくなりました!! もしよろしければ inst.IO = null; GC.Collect(); の働き、意味を回答箇所で教えていただきたいです。
guest

回答1

0

ベストアンサー

問題は inst.IO が COM オブジェクトだということです。.NET のオブジェクトであればクローズすることで全ての処理が終わり、ガベージコレクションでメモリが解放されるのを待つだけということを期待できますが、COM オブジェクトの場合はそれだけではなく COM インスタンスが解放されなければ次のインスタンスが作成できないことがあります。

.NET では、COM の解放はガベージコレクションによって自動的に行われます。しかしガベージコレクションが行われる前に次のインスタンスが作成されようとすると、古いインスタンスがまだ解放されていないために先ほど説明した不具合が生じます。

GC.Collect(); はガベージコレクションを強制的に行うメソッドです。これを行った時点で対象となるインスタンスは処理され、それが COM であった場合は解放されます。

inst.IO = null; は、ローカル変数から COM オブジェクトを切り離し、ガベージコレクションの対象に加えています。

このため、次の呼び出しまでに COM が解放され、不具合が無くなったのではないかと推測されます。

投稿2020/05/26 06:42

Zuishin

総合スコア28669

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mi-san

2020/05/26 06:49

COM オブジェクト、.NET のオブジェクトの違いも併せてご丁寧に教えていただきありがとうございました。inst.IO.Close(); だけでなんで上手くいかないんだろう?と疑問に思っていたので理解することも出来、とても助かりました。前回に引き続きありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問