C#でバックグラウンドワーカーを使用した時間表示の処理を行っております。
アプリケーションが起動している時は良いのですが、終了時に(1)の所で次のようなメッセージが出ます。
「破棄されたオブジェクトにアクセスする事は出来ません。」
「オブジェクトForm1です」
エラーを無くす方法についてご存知のかたいらっしゃいましたらご教授頂けないでしょうか。
//バックグラウンド処理の開始
private void Form1_Shown(object sender, EventArgs e) {
BackGroundWorker1.RunWorkerAsync(); //バックグラウンド処理開始
}
//バックグラウンド処理
private void BackGroundWorker1_DoWork(object sender, DoWorkEventArgs e) {
while (true){
Invoke(new SetTextDelegate(SetTime));//テキスト描画・・・・・(1)
}
}
//バックグラウンドから呼び出されるデリゲート関数
delegate void SetTextDelegate();
void SetTime() {
//時間の表示
label1.Text = DateTime.Now.ToString("日時:yyyy年MM月dd日 HH:mm:ss");
}
No.1ベストアンサー
- 回答日時:
InvokeメソッドはFormクラスのメンバ関数です。
Invokeが呼べるのはForm1オブジェクトが生きている間のみです。
bool GoBackGround = true;
など、フラグを作っておいて、FormClosingあたりでGoBackGround = false;にします。
で、
while (GoBackGround){
Invoke(new SetTextDelegate(SetTime));//テキスト描画・・・・・(1)
}
とかやれば、Form1がクローズ(破棄)されるとInvokeが呼ばれない為、エラーが出なくなるでしょう。
てゆ~か、アプリ終了時に、自分が作成したスレッドやバックグラウンドを放置して修了するのは、やっちゃいけないと思います。
アプリ内で作成したスレッドやバックグラウンドは、修了前に「自分で後始末」しましょう。
つまり「修了前に、スレッドやバックグラウンドを自分で破棄しないと駄目」です。
ちゃんと自分で破棄すれば、変なエラーは出ませんし、上記のようなフラグ操作も要りません。
ご回答頂きありがとうございます。
ご教授頂いたとおり修正した所解決しました。
内容といたしましては次のようになりました。
(1)bool GoBackGround = true;を追加
(2)FormClosingにGoBackGround = false;を追加
※この行のあとにApplication.DoEvents();を追加
(3)while (GoBackGround)とする
//バックグラウンド処理の開始
private void Form1_Shown(object sender, EventArgs e) {
GoBackGround = true;・・・・・・・・・・・・・・・(追加)
BackGroundWorker1.RunWorkerAsync(); //バックグラウンド処理開始
}
//バックグラウンド処理
private void BackGroundWorker1_DoWork(object sender, DoWorkEventArgs e) {
while (GoBackGround){・・・・・・・・・・・・・・(trueからGoBackGroundに変更)
Invoke(new SetTextDelegate(SetTime));//テキスト描画・・・・・(問題が起きていた箇所)
}
}
//バックグラウンドから呼び出されるデリゲート関数(この関数は変更無し)
delegate void SetTextDelegate();
void SetTime() {
//時間の表示
label1.Text = DateTime.Now.ToString("日時:yyyy年MM月dd日 HH:mm:ss");
}
// 閉じる前に呼ばれる
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
GoBackGround = false;・・・・・・・・・・・・・・・(追加)
Application.DoEvents();・・・・・・・・・・・・・(追加)※重要
}
以上、助かりました。
ありがとうございます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C#テキストボックスの文字を配列にいれてその後表示する 4 2022/07/17 04:47
- C言語・C++・C# 大量のデータを読み込んで表示する速度を改善したい 8 2023/05/07 13:29
- C言語・C++・C# C# で、あるフォルダー内にあるすべてのテキストファイルを別のフォルダーにコピーする。 4 2022/11/21 13:23
- C言語・C++・C# C# DatagridviewにExcelシートを反映するとエラーが出る 2 2023/05/06 17:12
- C言語・C++・C# Windows Formアプリからコンソールを呼び出して文字を出力させたい 8 2023/05/09 10:53
- Visual Basic(VBA) ExcelのVBAコードについて教えてください。 2 2023/05/23 16:28
- Access(アクセス) エクセルのVBAについて教えてください。 4 2023/01/21 10:21
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
- C言語・C++・C# TCP/IP通信時のサーバーからの受信 2 2022/11/23 09:11
- iPhone(アイフォーン) iPhone 14のバッテリー。 4 2023/07/19 20:41
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
数値の定数を付ける時
-
ラベルの表示までが異常に遅い...
-
JSP、サーブレットの初期処理
-
再度、スレッドが実行中かどう...
-
Tomcat高負荷時の設定について
-
WPF C#でF10のイベント取得方法...
-
処理実行後、終了させないで最...
-
JavaでVBのDOEVENTSと同様の処...
-
Windowsサービスの処理
-
doGetとdoPostの違い
-
tryの終了
-
Odbcオブジェクトの解放の方法
-
ftp 同時複数接続の負荷テスト...
-
アコーディオンメニューをアン...
-
Class.ForName("sun.jdbc.odbc....
-
データ未入力時のエラー処理が...
-
PHPでDB処理中にプログレスバー...
-
JavaScriptからJAVAクラスを呼...
-
switch文の中に、throws new Ex...
-
do - while文
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
tryの終了
-
doGetとdoPostの違い
-
Javaプログラムからポップアッ...
-
SwingUtilities.invokeLater(ne...
-
Javaでのデバッグコード削除
-
Tomcat高負荷時の設定について
-
JavaScriptからJAVAクラスを呼...
-
データ未入力時のエラー処理が...
-
アコーディオンメニューをアン...
-
ブラウザを閉じた後のサーバ側...
-
[Java] while(true)の意味
-
数値の定数を付ける時
-
Javaアプリケーション実行の返...
-
ラジオボタンの選択判定
-
onBlurとonFocusの処理順序につ...
-
スレッド1とスレッド2を交互に...
-
WPF C#でF10のイベント取得方法...
-
flush()メソッドについて・・・
-
ExcelVBA で文字列の特定の文字...
-
無限ループをわざと作って時計...
おすすめ情報