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

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

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

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

Q&A

解決済

3回答

7425閲覧

C# スレッド処理におけるスリープ処理の実装について

ryo_se

総合スコア68

C#

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

0グッド

0クリップ

投稿2016/06/14 13:42

お世話になっております。

現在ソケット通信を行うプログラムを作成しており、
アプリケーション終了時にソケット通信で電文送信を行う処理をコーディングしています。
電文送信直後にSocketクライアントをクローズすると処理が速すぎて送信ができないため、
Timerでスリープ処理を行いたいと思っています。

しかし下記コードを実行するとスリープは行われるのですが、
一通り処理が通った後にFormDesinersクラスで下記の例外が発生します。

System.InvalidOperationException' のハンドルされていない例外が
System.Windows.Forms.dll で発生しました。

追加情報: CreateHandle() の実行中は値 Dispose() を呼び出せません。

スレッドが関係しているような気がするのですが、原因がつかめません。
対策方法があればご教示いただければ幸いです。

//コードは何か所か省略しています。Formクラスの記述です。 SocketSendClass listening; // スレッド利用する接続待ち用兼電文送信用クラス private void Form1_FormClosed(object sender, FormClosedEventArgs e) { // サーバアプリを終了するにもかかわらず、接続待ちスレッドを終了していない場合の処理 if (SLTAlive) { if (listening.ClientSocket != null) { //電文を送信 listening.send(true, true); } //1秒後にchangeBtnTimeAfterメソッドを実行 System.Threading.Timer timer = new System.Threading.Timer(Close, null, 1000, 0); } } private void Close(Object state) { if (listening.ClientSocket != null) { // Socketクライアントをクローズ listening.ClientSocket.Shutdown(SocketShutdown.Both); listening.ClientSocket.Close(); listening.ClientSocket = null; } if (ServerSocket != null) { // 接続要求受け入れの終了 ServerSocket.Close(); } // 念のためスレッドをnull設定 StartListeningThread = null; // スレッド終了指示フラグを終了に設定 SLTAlive = false; }

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

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

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

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

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

guest

回答3

0

ベストアンサー

こんにちは。

Form1のクローズ処理をブロックしていませんので、サブ・スレッドで1秒待っている間に、Form1のクローズ処理が進行します。アプリケーション終了時ですので、それに続いてForm1オブジェクトも破棄されます。この処理には1秒もかからないことが多いと思います。
その結果、1秒後にForm1のClose()が呼び出されますが、Form1オブジェクトは既に破棄されているので異常動作すると思います。

単純に、System.Threading.Timer timer = new System.Threading.Timer(Close, null, 1000, 0);の代わりに、System.Threading.Sleep(1000); Close();ではダメでしょうか?
アプリケーショが1秒程度無応答になっても普通は気にならないと思います。まして、アプリ終了時ですから、気にする人はいない筈です。

投稿2016/06/14 14:26

Chironian

総合スコア23272

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

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

ryo_se

2016/06/24 10:28

返事が遅くなってすみません、どうやら別のスレッド処理の部分でクローズしている最中にスレッド内の処理が進んでいたことが問題のようでした。
guest

0

クローズしてから別スレッドで送信するのは悪手です。資源の解放が始まります。送信してからクローズするのが常道です。

投稿2016/06/14 13:53

Zuishin

総合スコア28660

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

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

0

Form1がクローズされて1秒後に、存在しないインスタンスのCloseが呼ばれているように見えます。
現在のスレッドに対してSleepすればいかがでしょうか。

投稿2016/06/14 13:53

moonphase

総合スコア6621

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問