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

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

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

Re[6]: スレッドでメッセージを表示したい。


(過去ログ 129 を表示中)

[トピック内 9 記事 (1 - 9 表示)]  << 0 >>

■76703 / inTopicNo.1)  スレッドでメッセージを表示したい。
  
□投稿者/ ミーアキャット (1回)-(2015/08/05(Wed) 09:56:44)

分類:[.NET 全般] 

VisualStudio 2013 .Net 4.0 です。

スレッドの方法を知りたくていろいろ検索して回ったのですが
まったくわかりませんでした。
よく、ネットを調べていると
Console.WriteLine("");
というのが使用されているのですが何も表示されない。
Windows フォームアプリケーションだからでしょうか?

一般には、コンソールアプリケーションでしか
プログラムは作られていないということですか?
または、Console.WriteLine を表示する方法がありますか?

表示されないので、代替えとして
MessageBox.Show() で置き換えたりするのですが
今回は、コンソールの代替えとして RichTextBox を使いました。
(他には、TextBoxのマルチラインしか思い浮かびませんが。)

最終的にはスレッドで計算された値を List<int>に

以下、まったく理解できないので中途半端なプログラムで、
ビルドもできませんが、行き詰っています。

ボタンクリックでスレッド処理を行う worker を設定してスレッド実行する。
スレッドで実行されているworker から 文字列を表示させる


public partial class Form1 : Form
{
 List<int> datalist = new List<int>();

 public Form1()
 {
  InitializeComponent();
 }

 private void button1_Click(object sender, EventArgs e)
 {
  Thread t = new Thread(new ThreadStart(worker));
  t.Start();
 }

 delegate void AppendTextDelegate(string msg);
 AppendTextDelegate Appendtext;

 void worker()
 {
  Appendtext = new AppendTextDelegate("123\r\n"); ←() だと 引数がないとエラーが出るので


  datalist 作成(時間がかかる)を行う。
 }
}


追記:
Task(async/await) を使うという方法も見かけたのですが、こちらの方は
全く理解できず。サンプルも動作しませんでした。

public async void SampleAsync() {・・・・}
async が存在しなかったので断念。











引用返信 編集キー/
■76704 / inTopicNo.2)  Re[1]: スレッドでメッセージを表示したい。
□投稿者/ 774RR (292回)-(2015/08/05(Wed) 10:11:34)
まったくわかりません、ではここでオイラたちが解説してもわからないに違いないので
訊くだけ無駄というか、もうちょっと的を絞っておくれ。

Console.WriteLine はいわゆるコマンドプロンプトや PowerShell の画面上に文字を表示する機能なので
俗に言う CUI (Character User Interface) なプログラム上で使うものだ。
GUI (Graphical User Interface) なプログラム上で使うには向かない。

んで・・・
スレッドの勉強をするには実は GUI プログラムは結構制約が多くて、
「勉強のための勉強」ならば CUI でプログラムはじめてみるのがいいかもしれない。

提示コードは、「そりゃ動かないよ・・・」という感じなんだが・・・
ぢゃ何から解説すればいいかというとリンダ困っちゃう。

引用返信 編集キー/
■76705 / inTopicNo.3)  Re[2]: スレッドでメッセージを表示したい。
□投稿者/ ミーアキャット (3回)-(2015/08/05(Wed) 10:30:30)
No76704 (774RR さん) に返信
すみません。
早速の回答ありがとうございます。

Console.Write は結局 MessageBox.Showに置き換えるか
今回のようにリッチテキストボックスに表示するしか手がないみたいですね。

スレッドの方ですがフォームに貼り付けてあるリッチテキストボックスに
メッセージを表示する方法を教えてください。
10%・・・20%・・・30%・・・・・・100%と表示してみたい

 private void button1_Click(object sender, EventArgs e)
 {
  Thread t = new Thread(new ThreadStart(worker));
  t.Start();
 }

 void worker()
 {
    ←リッチテキストボックスにメッセージを表示する方法
 }



引用返信 編集キー/
■76706 / inTopicNo.4)  Re[3]: スレッドでメッセージを表示したい。
□投稿者/ 774RR (293回)-(2015/08/05(Wed) 10:51:21)
.NET の GUI プログラミングの固有の制約として
・計算は WorkerThread で行うことができるが
・画面の更新は UI スレッドで行う必要がある
という仕様になっている。

で・・・ System.Threading.Thread を明示して使うのは、今となっては古い方式なんだが、
・温故知新、勉強のための勉強と割り切って古い方式から始めてみる?
・もっと新しくて使いやすい BackgroundWorker を使ってみる?

引用返信 編集キー/
■76709 / inTopicNo.5)  Re[4]: スレッドでメッセージを表示したい。
□投稿者/ ミーアキャット (4回)-(2015/08/05(Wed) 11:21:36)
No76706 (774RR さん) に返信

・もっと新しくて使いやすい BackgroundWorker を使ってみる?

Threading.Thread の方法がネット上では主流になっていたので
使用しましたが、できれば 新しい方法の
BackgroundWorker を使いたいです。
引用返信 編集キー/
■76711 / inTopicNo.6)  Re[3]: スレッドでメッセージを表示したい。
□投稿者/ 魔界の仮面弁士 (435回)-(2015/08/05(Wed) 11:35:51)
No76705 (ミーアキャット さん) に返信
> Console.Write は結局 MessageBox.Showに置き換えるか
Windows Forms アプリケーションの場合、Console.Write や Debug.Write の結果は、
既定では Visual Studio の「出力」ペインに表示されます。

(Debug.Write については、Visual Studio のオプション設定を変更することで、
「出力」ではなく「イミディエイト」に表示させることもできます)


> 今回のようにリッチテキストボックスに表示するしか手がないみたいですね。

NG です。複数のスレッドを使う場合は、動作を UI 要素で確認することは避けてください。
複数のスレッドを扱う時は、『同時実行制御』をきちんと意識してコーディングしましょう。

そもそもワーカスレッド内から、UI スレッドで管理するオブジェクト(コントロール等)を直接操作するのは厳禁です。


ワーカースレッドに作業させた結果を、UI スレッドで受け取って表示させるとか、
作業進捗の表示を、ワーカースレッド側が UI スレッドに「依頼」する、というのならば OK ですが、
ワーカースレッド内から、他のスレッドで管理されているオブジェクトを直接操作することは基本的に NG です。

まぁ、そのオブジェクトがスレッドセーフな設計になっていれば、直接操作することも可能ですが、
少なくとも RichTextBox はスレッドセーフではありませんしね。


たとえば
 private int money = 1000;
というフィールド変数があったとしましょう。
そしてこれを、複数のスレッドAとBから、ほぼ同時に money += 1 したとします。

《パターン1》
(1) Aが、変数money から値を読み取る。(Aのメモリ値=1000、money=1000)
(2) Aが、読みとった値に +1 を加える。(Aのメモリ値=1001、money=1000)
(3) Bが、変数money から値を読み取る。(Bのメモリ値=1000、money=1000)
(4) Bが、読みとった値に +1 を加える。(Bのメモリ値=1001、money=1000)
(5) Aが、加算した値を変数に書き戻す。(Aのメモリ値=1001、money=1001)
(6) Bが、加算した値を変数に書き戻す。(Bのメモリ値=1001、money=1001)
(7) 変数 money の最終値は 1001 円。

《パターン2》
(1) Aが、変数money から値を読み取る。(Aのメモリ値=1000、money=1000)
(2) Aが、読みとった値に +1 を加える。(Aのメモリ値=1001、money=1000)
(3) Aが、加算した値を変数に書き戻す。(Aのメモリ値=1001、money=1001)
(4) Bが、変数money から値を読み取る。(Bのメモリ値=1001、money=1001)
(5) Bが、読みとった値に +1 を加える。(Bのメモリ値=1002、money=1001)
(6) Bが、加算した値を変数に書き戻す。(Bのメモリ値=1002、money=1002)
(7) 変数 money の最終値は 1002 円。

単純な int 値でさえ、わずかな処理タイミングの違いで、
結果が異なってしまうことがありえるというわけです。


そのため、マルチスレッドでデータをやり取りする場合は、
 (案1)ローカル変数以外は使わない。(変数を異なるスレッドで共有しない)
 (案2)非ローカル変数を利用するが、1つの変数を1つのスレッドだけで利用する。
 (案3)1つの変数を複数の非同期スレッドから利用するが、変数のアクセス部分だけは同期化させ、共有データが同時にアクセスさせれないよう排他制御する。
といった対処が求められます。
たとえば案3 なら、System.Threading.Interlocked.Add(ref money, 1); みたいにするなど。


> スレッドの方ですがフォームに貼り付けてあるリッチテキストボックスに
> メッセージを表示する方法を教えてください。

.NET 2.0 以降なら、Thread を自分で生成するよりも、BackgroundWorker に任せた方が実装が簡単です。
.NET 4 以降では、Task (async / await) の方が一般的かな…。
http://kimux.net/?p=902
引用返信 編集キー/
■76712 / inTopicNo.7)  Re[5]: スレッドでメッセージを表示したい。
□投稿者/ 774RR (294回)-(2015/08/05(Wed) 11:40:20)
BackgroundWorker で検索してもサンプルページはいくつもヒットするわけだけだ。
オイラたちが掲示板の狭い場で説明するより詳しく書かれているので、まずはそっち読んで欲しい。
んで「このページのここがわからない」なら解説してあげられる(と思う)

今の時点で言えるのは、提示コード例は
・ button1_Click のイベントハンドラ内部の局所変数として Thread を作っている
・このスレッドオブジェクトは button1_Click のイベントハンドラを抜けた時点で参照数0になる
・なので、スレッドが走り続ける前にガベージコレクションの対象となって消滅している

Thread オブジェクトなり BackgroundWorker オブジェクトなりは、処理完了するまで gc されないように、
・処理完了まで button1_Click に留まるか(マルチスレッドにする意味がほぼ無い)
・BackgroundWorker をフォームのメンバとしておくか
必要があるわけだ。

というわけで google 様に BackgroundWorker で訊いてみた結果の一部とか
http://www.atmarkit.co.jp/fdotnet/dotnettips/436bgworker/bgworker.html
http://dobon.net/vb/dotnet/programing/progressdialogbw.html
http://yas-hummingbird.blogspot.jp/2008/12/backgroundworker.html

引用返信 編集キー/
■76713 / inTopicNo.8)  Re[4]: スレッドでメッセージを表示したい。
□投稿者/ ミーアキャット (6回)-(2015/08/05(Wed) 12:49:04)
No76711 (魔界の仮面弁士 さん) に返信

> 既定では Visual Studio の「出力」ペインに表示されます。
出力されてました。今までMessageBox.Show で置き換える必要が
なくなりました。ありがとうございます。


> .NET 2.0 以降なら、Thread を自分で生成するよりも、BackgroundWorker に任せた方が実装が簡単です。
> .NET 4 以降では、Task (async / await) の方が一般的かな…。

Task (async / await) 挑戦してみます。
引用返信 編集キー/
■76728 / inTopicNo.9)  Re[6]: スレッドでメッセージを表示したい。
□投稿者/ ミーアキャット (7回)-(2015/08/06(Thu) 16:17:38)
まだ、ちょっと理解できませんけど
頑張ってみます。

わからないところがあればまた教えてください。

とりあえず、解決とします。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -