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

わんくま同盟

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

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

ツリー一括表示

C# タスクとオブジェクト /まりも (20/12/24(Thu) 13:24) #96605
Re[1]: C# タスクとオブジェクト /Hongliang (20/12/24(Thu) 13:39) #96608
  └ Re[2]: C# タスクとオブジェクト /まりも (20/12/24(Thu) 13:46) #96610
    └ Re[3]: C# タスクとオブジェクト /Hongliang (20/12/24(Thu) 14:00) #96612
      └ Re[4]: C# タスクとオブジェクト /まりも (20/12/24(Thu) 14:14) #96613
        └ Re[5]: C# タスクとオブジェクト /まりも (20/12/24(Thu) 14:33) #96614 解決済み


親記事 / ▼[ 96608 ]
■96605 / 親階層)  C# タスクとオブジェクト
□投稿者/ まりも (1回)-(2020/12/24(Thu) 13:24:30)

分類:[C#] 

C#勉強中です。
タスクの動作で疑問点が出てきまして、色々調べてみたのですが
いまいち納得できる理由がわかりませんでしたので質問させてください。

下記、Task_Proc()を動作中、ボタンイベントを実施し、それぞれが
UpdateText()を呼び出す動作をします。
この際、ボタンイベント後、Invokeが実施されなくなりました。
コードにはありませんが、ボタンイベントを抜けるようにすると
Task_Proc()がまだ動作し始めました。
なぜ非同期で交互に動いてくれないのでしょうか?
ちなみにラベルの操作を行わないようにすると非同期動作しました。

ボタンイベントが優先度が高くて、終わるまで占有される?
それにしてはラベル操作がないと同時に動いているようにみえました。

同時に更新を行うようにするにはどのように処理すればよいのでしょうか?

よろしければ助言いただけると助かります。



// タスク
private void Task_Proc()
{
while (true)
{
System.Threading.Thread.Sleep(1000);
System.Diagnostics.Debug.WriteLine(">>> loop1");
UpdateText();
}
}

// タスク実行
Task task = Task.Run(() => {
Task_Proc();
});

// 共通呼び出し
private void UpdateText()
{
if (this.InvokeRequired)
{
this.Invoke((MethodInvoker)(() => Lbl.Text = "Invoke実施"));
return;
}
else
{
Lbl.Text = "通常実施";
}
}

// イベント
private void Ini_Click(object sender, EventArgs e)
{
while (true)
{
System.Threading.Thread.Sleep(1000);
System.Diagnostics.Debug.WriteLine(">>> loop2");
UpdateText();
}
}

[ □ Tree ] 返信 編集キー/

▲[ 96605 ] / ▼[ 96610 ]
■96608 / 1階層)  Re[1]: C# タスクとオブジェクト
□投稿者/ Hongliang (1134回)-(2020/12/24(Thu) 13:39:29)
UpdateText()内でInvokeしていますが、これはGUIスレッドに処理を依頼するものです。
で、そのGUIスレッドはIni_Click内でずっと動作し続けているので、依頼された処理を実行することができません。

Ini_Click内の処理も同じようにTask.Runで別スレッド処理にしてやれば、GUIスレッドは占有される仕事がなくなるので、Invokeが行われたときにその依頼された処理を実行できるようになります。
[ 親 96605 / □ Tree ] 返信 編集キー/

▲[ 96608 ] / ▼[ 96612 ]
■96610 / 2階層)  Re[2]: C# タスクとオブジェクト
□投稿者/ まりも (2回)-(2020/12/24(Thu) 13:46:31)
No96608 (Hongliang さん) に返信
> UpdateText()内でInvokeしていますが、これはGUIスレッドに処理を依頼するものです。
> で、そのGUIスレッドはIni_Click内でずっと動作し続けているので、依頼された処理を実行することができません。
>
> Ini_Click内の処理も同じようにTask.Runで別スレッド処理にしてやれば、GUIスレッドは占有される仕事がなくなるので、Invokeが行われたときにその依頼された処理を実行できるようになります。

回答ありがとうございます。
ちなみに、ラベルへの書き込みをコメントアウトして動作させるとログが相互に出力されて非同期実行されているように見えるのは何故でしょうか?

[ 親 96605 / □ Tree ] 返信 編集キー/

▲[ 96610 ] / ▼[ 96613 ]
■96612 / 3階層)  Re[3]: C# タスクとオブジェクト
□投稿者/ Hongliang (1135回)-(2020/12/24(Thu) 14:00:49)
「ラベルへの書き込み」って具体的にはコードのどの部分でしょうか。
2か所の
> UpdateText();
を消したのであれば、GUIスレッドとTask.Runで動くスレッドの2つで並行して動くのは当然のことですが。

// 何が疑問なのかわからないので答えられている気がしない
[ 親 96605 / □ Tree ] 返信 編集キー/

▲[ 96612 ] / ▼[ 96614 ]
■96613 / 4階層)  Re[4]: C# タスクとオブジェクト
□投稿者/ まりも (3回)-(2020/12/24(Thu) 14:14:54)
No96612 (Hongliang さん) に返信

すみません。理解しました。
UpdateText()を外せば別々の処理になりますね。
ありがとうございました。
[ 親 96605 / □ Tree ] 返信 編集キー/

▲[ 96613 ] / 返信無し
■96614 / 5階層)  Re[5]: C# タスクとオブジェクト
□投稿者/ まりも (4回)-(2020/12/24(Thu) 14:33:25)
No96613 (まりも さん) に返信
> ■No96612 (Hongliang さん) に返信
>
> すみません。理解しました。
> UpdateText()を外せば別々の処理になりますね。
> ありがとうございました。
解決済み
[ 親 96605 / □ Tree ] 返信 編集キー/


管理者用

- Child Tree -