C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト


■87555 / )  Re[4]: ロード中に表示するフォームを別スレッドで
□投稿者/ MTK (68回)-(2018/06/05(Tue) 15:30:30)
No87552 (とっちゃん さん) に返信

>>・エラーが発生している原因と解決策
> Task.Run() で作成部分だけスレッドアウトした形にしていますよね?
> フォームを作成したらタスクが終了してしまうため、
> そのフォームを作ったスレッドがどこかに行ってしまいます。
>
> また、Taskで割り当てされるスレッドは、MTAモードなので、フォーム作成を行うのには向きません。

なるほど!そういうことだったんですね。
MTAとSTAのことは知りませんでした。勉強になりました。
エントリポイントで[STAThread]を宣言していてもTaskで実行するとMTAモードになるんですかね
スレッドがどこかに行ってしまうのであれば、ロード中フォームのスレッドを維持してやればいいんでしょうか?


>>発生場所については
>>TopMenuForm.cs の
> >>this.formMgr.SetLoadText("会社データロード中..."); // ここでエラー
>>
>>というところまでは分かっています。
>
> この部分は、await から戻ってきてから動く部分ですよね?

はい、この部分は戻ってきてから動く部分です。



> フォームは、STAで動かす必要があり、なおかつそのSTAは、UIスレッドである必要があります。

フォームはSTAでかつUIスレッドである必要がある というのは、
フォームはメインスレッドで呼び出す必要があり、Task.Run のような別スレッドで呼び出してはいけないという理解で正しいでしょうか?



> 詳細は省きますが、UIスレッドを自力で起こせない場合は、

すいません、ここの部分は自分でも調べてみたのですが、まだ理解できていません。
UIスレッドを自力で起こせない場合 というのが理解できていないのですが、どういう意味でしょうか?



> メインスレッド(メインのフォームを作成しているスレッド)でフォームを作り、時間のかかる処理を別スレッドにするほうが構造上は安定します。

今回の例の場合はどうするべきでしょうか?
メインスレッドで Aフォームを表示した際に、ロード中フォームを別で前面に出したいのです。
Aフォームのロード処理を別スレッドにしたとしても、
Aフォームもロード中フォームもメインスレッドで表示しなければいけないんですよね?



> 今回のようなプログラムであれば
>
> public void InitLoadFormAsync()
> {
> loadForm = new LoadScreenForm();
> loadForm.Show();
> }
> private async void OnLoad(object sender, EventArgs e)
> {
> SetLoadText( "会社データロード中..." ); // 中身はInvokeではなく直接セットに変える(実装がぐちゃぐちゃで実現できないので省略)
> await Task.Run( ()=> データロードの時間のかかる処理() );
> // 処理終了後に何かやりたいなら、ここでやる(ログイン中...に変える?)
> }
>
> という感じにすれば、安定すると思いますよ。
> 書きなぐりコードなので、自分の都合に合わせて直してくださいね。


プログラムまでいただいてありがとうございます。
調べて内容をきちんと理解できるようにしたいと思います。
返信 編集キー/


管理者用

- Child Tree -