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

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

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

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

Q&A

解決済

1回答

739閲覧

関連するライブラリーやDLLのロード完了までウエイトしたい

ysh_ktd

総合スコア11

C#

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

0グッド

0クリップ

投稿2020/03/27 05:14

ノートPCで、時々Invokeで例外が発生します。

C#でメイン処理スレッドで処理し、必要に応じてGUIの変更を行うという構成のソフトを開発しています。
スレッドからGUIを変更する為、Task.Run()とInvoke()を使用し、以下の様な感じで使用しています。

Task.Run(() => { Invoke((MethodInvoker)(() => { // テキストボックスなどコントロールへのアクセス } )); });

開発環境は、Visual Studio Express 2017 for Windows Desktop です。

アプリを起動した直後、Invoke()が見つかりません、という内容の例外が発生してしまいます。
状況は以下の通りです。

  • 起動直後だけで、その後は発生しない。
  • デスクトップPCでは発生しない。
  • 複数台のノートPCで起動させましたが、発生するPCとしないPCがありました。
  • 感覚的には、ノートPCが省電力モードに入っていて、起動に時間がかかり、Invoke関連のファイルが読み込まれないうちにInvokeを読んでいる感じです。

アプリ起動時に、関連するライブラリー、DLL等のロードが終わったことを確認し、処理を開始すれば回避出来ると考えています。
C#で関連ファイルのロードが終わるまで、ウエイトする方法は無いでしょうか?

もしくは、全然、別の要因でしょうか?

よろしくお願いします。

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

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

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

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

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

Zuishin

2020/03/27 05:24

こちらで再現可能な最小のコードを新規作成して掲載してください。
ysh_ktd

2020/03/27 05:50 編集

起動直後に、テキストボックスに初期値を表示しています。 起動時に例外が発生して更新されないのですが、その後、MainLoopスレッドで同じ関数を呼び出すと、ちゃんと更新されます。 ``` public Form1() { InitializeComponent(); UpdateDataBasePath(@"Test") ......................... // Main Task 起動 Task.Run(() => { this.MainLoop(); }); Console.WriteLine("Main Init OK !"); } private void UpdateDataBasePath(string mes) { Task.Run(() => { Invoke((MethodInvoker)(() => { txtBoxDataBasePath.Text = mes; } )); }); } ``` よろしくお願いします。
Zuishin

2020/03/27 05:50

「.....」と MainLoop でエラーになります。 「こちらで再現可能な」 「最小のコードを」 「新規作成して」 掲載してください。
Zuishin

2020/03/27 05:51

もちろん、新規作成した後は、 「再現することを確認してから」 掲載してください。
pepperleaf

2020/03/27 11:26

質問文の編集で、問題の発生したコードと、実際のエラー内容の記載をお願いします。
guest

回答1

0

自己解決

発生した例外は以下の通りです。

"ウィンドウハンドルが作成される前コントロールでinvokeまたはbegininvokeを呼び出せません"

メッセージの内容から、タイミングの問題と考えてしまいました。

根本的に間違えているのですが、ノートPCかつ発生確率が低いという状況でした。その為、どの様にコードを提示したら良いか分からず、返信が遅れてしまい、申し訳ありません。

スレッドからGUIを変更するコードをWEBで探し試した結果、以下のコードで問題が発生しなくなりました。

private void UpdateControl(string s) { if (txtBox.IsDisposed) return; if (txtBox.InvokeRequired) { txtBox.Invoke((MethodInvoker)delegate {UpdateControl(s);}); } else { txtBox.Text = s; } }

GUIを変更するのにはデリゲートだけで良く、Task.Run()で実行したのがまずかったと考えています。

色々とお手数をお掛けして申し訳ありませんでした。

投稿2020/04/02 04:27

ysh_ktd

総合スコア11

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問