BackgroundWorkerについて(C#)

このQ&Aのポイント
  • C#のBackgroundWorkerを使ったプログラムで、プログレスバーが終了する前に「終了」と表示されてしまう理由はなぜでしょうか?
  • Windows Form上にButtonとProgressBarを設置し、BackgroundWorkerを使用してプログレスバーを表示させるプログラムを作成しました。しかし、プログレスバーが終了する前に「終了」と表示されてしまいます。なぜこのような現象が起きるのでしょうか?
  • C#のBackgroundWorkerを使用したプログラムで、プログレスバーの状態が終了する前に「終了」と表示される理由を教えてください。
回答を見る
  • ベストアンサー

BackgroundWorkerについて(C#)

C#でBackgroundWorkerを使ったプログラムを試しています。 Windows Form上にButtonとProgressBarを設置して以下のプログラムを 動作させると、プログレスバーが終了するまえに”終了”が出てしまいますが これはどうしてでしょうか? よろしくお願いいたします。 using System; using System.ComponentModel; using System.Threading; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { button1.Enabled = false; Random rand = new Random(); BackgroundWorker bgWorker = new BackgroundWorker(); bgWorker.DoWork += ((sender2, e2) => { for (int i = 0; i < 10; i++) { Thread.Sleep((int)(rand.NextDouble() * 500)); bgWorker.ReportProgress((i + 1) * 10); } }); bgWorker.RunWorkerCompleted += ((sender2, e2) => { button1.Enabled = true; bgWorker.Dispose(); MessageBox.Show("終了"); }); bgWorker.ProgressChanged += ((sender2, e2) => { progressBar1.Value = e2.ProgressPercentage; }); bgWorker.WorkerReportsProgress = true; bgWorker.RunWorkerAsync(); } } }

質問者が選んだベストアンサー

  • ベストアンサー
  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.1

>プログレスバーが終了するまえに”終了”が出てしまいますが >これはどうしてでしょうか? 単純にタイミングの問題なんじゃないですかねぇ…。 >progressBar1.Value = e2.ProgressPercentage; でプログレスバーの値が書き換わりますが、再描画の指示がメッセージキューに積まれます。 で、その再描画を処理する前にRunWorkerCompletedが処理されてしまった。 ということかと。 実行している環境のスペック次第でそこら辺は変わるかも知れません。 # というかこちらではそんな事になりませんでしたし……。 MessageBox.Show()の前にprogressBar1.Update()とか入れてみたらどうなりますかね? # まあ、このタイミングで再描画強制できるかどうかは不明ですが。 # button1.Enabled = true;でのボタンの再描画は走っているみたいですからイケますかねぇ…。 あと……テストだからいいかも知れませんが、DoWorkでResult設定した方がいいんじゃないですかね。

関連するQ&A

  • backgroundworkerについて C#

    C# 2005で、backgroundworker1.RunWorkerAsync(100);とした場合は、 DoWorkイベントでbgWorkerArgが以下のように100になるのはわかりますが、 int bgWorkerArg = (int)e.Argument; 例えば2つの文字列を送る場合や、構造体を送ることは可能でしょうか? 簡単なサンプルがあれば助かります。 あと、DoWorkイベントの中で // senderの値はbgWorkerの値と同じ BackgroundWorker woker = (BackgroundWorker)sender; としているサンプルを見つけましたが、この後 workerは一般的に何に使うのでしょうか?サンプルでは、何も使っていませんでした。 Threadよりbackgroundworkerを使うように書かれているものも見ましたが 薦めている理由も知りたいです。

  • C# 簡単なシューティング 自機移動について

    かなりの初心者で困っています。 簡単なシューティングを作ろうとおもっています。 使用ソフトはVisualC#2005です。 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace WindowsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } //自機(右移動) private void button3_Click(object sender, EventArgs e) { if (timer1.Enabled == false) { timer2.Enabled = false; timer1.Enabled = true; } else { timer1.Enabled = false; timer3.Enabled = false; timer4.Enabled = false; } } private void timer1_Tick(object sender, EventArgs e) { pictureBox1.Left = pictureBox1.Left + 2; } //自機(左) private void button4_Click(object sender, EventArgs e) { if (timer2.Enabled == false) { timer1.Enabled = false; timer2.Enabled = true; } else { timer2.Enabled = false; timer3.Enabled = false; timer4.Enabled = false; } } private void timer2_Tick(object sender, EventArgs e) { pictureBox1.Left = pictureBox1.Left - 2; } //自機(上) private void button1_Click(object sender, EventArgs e) { if (timer3.Enabled == false) { timer4.Enabled = false; timer3.Enabled = true; } else { timer1.Enabled = false; timer2.Enabled = false; timer3.Enabled = false; } } private void timer3_Tick(object sender, EventArgs e) { pictureBox1.Top = pictureBox1.Top - 2; } //自機(下) private void button2_Click(object sender, EventArgs e) { if (timer4.Enabled == false) { timer3.Enabled = false; timer4.Enabled = true; } else { timer1.Enabled = false; timer2.Enabled = false; timer4.Enabled = false; } } private void timer4_Tick(object sender, EventArgs e) { pictureBox1.Top = pictureBox1.Top + 2; } } } 自機は画像(PictureBox)でボタンによって上下左右に移動します。 FormのSizeは800,630です。 自機の移動がボタンなのでキー入力によって操作できるようにしたいのですが、 それと、自機の移動範囲を画面からでないようにしたいです。 あまりC#を理解できてない上でつくったのでおかしな点が多々あると思います。 教えていただける方がいると助かります。

  • Visual c# スレッド

    プログラム初心者です。 Visual c#にてスレッド関数を使ったプログラムを見よう見まねで 作りました。 スタートボタンを押すとピクチャーボックスの位置が 左から右へ移動し、ストップボタンを押すと止まる。 ピクチャーボックスの位置をテキストボックスに表示する。 というプログラムのつもりです。 デバックの状態でスタートボタンを押すとエラーメッセージが出て テキストボックスに位置を書き込むの関数のところが緑色にハイライトされます。エラーの内容は「有効でないスレッド間の操作」とありますが、どうしたら良いのか分かりません。 エラーの直し方を教えてください。 プログラムコードは以下です。 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Threading; namespace bit_map_08._1._ { public partial class Form1 : Form { private Thread thread; static private int Position = 0; static private int i; static bool BtnOnFig; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { thread = new System.Threading.Thread(newSystem.Threading.ThreadStart(MainThread)); thread.Start(); } private void PointMove() { if (i < 300) { i = i + 1; Position = Position + i; textBox1.Text = Convert.ToString(Position); pictureBox1.Left = (Position); } if (i == 300) { i = 0; } } private void MainThread() { while( true ) { Thread.Sleep(100); if (BtnOnFig == true) { PointMove(); } } } private void button1_Click(object sender, EventArgs e) { BtnOnFig = true; } private void button2_Click(object sender, EventArgs e) { BtnOnFig = false; } } }

  • C# フォームを閉じてもプログラムが終了しない

    前略 ・C#の初心者です。 ・下記のようなプログラムを作りたいと思っています。プログラムは<作りたいプログラム>の仕様どうりに動作していますが、Form1のFormClosingイベントに Application.Exit()を追加しないと フォーム1で "X"(閉じる)をクリックしても(フォームは非表示になりますが)プログラムが終了しません。プログラムでどこかおかしな部分があると思っています。Application.Exit()を追加しないでもプログラムを終了する方法を教えてください。 <作りたいプログラム> (1)Form1 のbutton1をクリックすると新しいForm2が作成され表示される。Form2が表示されるとForm1は非表示となる。 (2)Form2 のbutton1をクリックするとForm2が非表示となりForm1が表示される。 (3)Form1 の "X"(閉じる)をクリックしてプログラムを終了する。 //Form1.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace formClose { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { Form2 form2 = new Form2(); form2.Show(); //フォーム2を表示 this.Hide(); //フォーム1を非表示 } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { Application.Exit(); //アプリケーション終了 } } } //Form2.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace formClose { public partial class Form2 : Form { Form1 form1 = new Form1(); public Form2() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { this.Close(); //フォーム2を閉じる } private void Form2_FormClosing(object sender, FormClosingEventArgs e) { form1.Show(); //フォーム1を表示する } } } 以上

  • C#の配列の定数

    BCCを使用していたのですが、最近VS2013でC#を勉強し始めました フォームの指定した位置にいくつかのボタンを設置し、あらかじめ定義しておいた テーブルからボタンのtextを表示したいと思い、以下のようにコーディングしたのですが エラーが出てしまい思ったような結果に持って行くことができません C#ならこうした方がいいという指摘も含めて どうやるのがいいのか ご教授ください 足りない情報があれば追加します ちなみにまだテスト段階だから2列定義して1列しか表示するようにしかなってません ----------------------------------------------------------------------- using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace haneda { public partial class Form1 : Form { private Button[] buttons; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { int i; //ボタンコントロール配列の作成 this.buttons = new Button[table.MAX_R]; for (i = 0; i < buttons.Length; i++) { //ボタンコントロールのインスタンス作成 this.buttons[i] = new Button(); //プロパティ設定 this.buttons[i].Name = "btn" + i.ToString(); this.buttons[i].Text = table.roomNo[1, i]; <=ここがエラー this.buttons[i].Top = table.roomX01[i]; <=ここがエラー this.buttons[i].Left = table.roomY01[i]; <=ここがエラー this.buttons[i].Click += new System.EventHandler(button_Click); //コントロールをフォームに追加 this.Controls.Add(this.buttons[i]); } } private void button_Click(object sender, System.EventArgs e) { Button btn = (Button)sender; MessageBox.Show(btn.Name); } } public class define { public const bool IGNORE = false; //非表示 public const bool EFFECT = true; //表示 /* 最大値 */ public const int MAX_F = 2; //フロア数 public const int MAX_R = 3; //ルーム数 } public class table { /* ナンバー */ public readonly string[,] roomNo = new string[define.MAX_F, define.MAX_R] { { "101", "102", "103"}, { "201", "202", "203"} } /* 表示・非表示 */ public readonly bool[,] effectRoom = new bool[define.MAX_F, define.MAX_R] { {EFFECT, IGNORE, EFFECT}, {EFFECT, EFFECT, EFFECT} } public readonly int[] roomX01 = new int[define.MAX_R] { 5, 70, 135 } public readonly int[] roomY01 = new int[define.MAX_R] { 100, 100, 100 } } }

  • C#での時間制限のプログラム

    C#初心者です。Visual studioでプログラムを書いてます。 ラベルに制限時間を表示させ、起動して30秒経つと 「もういちどやりますか?」というメッセージボックスが出て、 「はい」でもう一度開始、「いいえ」でプログラムを終了させるような 処理をさせたいのですが、「はい」を押しても同じメッセージボックスが出てループしてしまい、もう一度開始させることができません…。 解決する方法を教えていただきたいです。よろしくお願いします。 以下、書いたコードです。 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace timelimit { public partial class Form1 : Form { public Form1() { InitializeComponent(); } DateTime StartTime; TimeSpan TimeLimit; private void Form1_Load(object sender, EventArgs e) { timer1.Enabled = true; StartTime = DateTime.Now; TimeLimit = new TimeSpan(0,0,30); } private void timer1_Tick(object sender, EventArgs e) { TimeSpan tm = DateTime.Now - StartTime; if(tm > TimeLimit) { TimeLimit = new TimeSpan(0, 0, 30); timer1.Enabled = false; DialogResult result = MessageBox.Show ("時間終了!もういちどやりますか?","終了処理",MessageBoxButtons.YesNo); if (result == DialogResult.Yes) { timer1.Enabled = true; } else if (result == DialogResult.No) { Close(); } }else{ label1.Text = (TimeLimit - tm).ToString(); } }

  • C#でstop()が使えない。

    http://kana-soft.com/tech/sample_0012_3.htm#WebBrowser_Stop このHPを参考にstop()メソッドを使おうとしたのですがSTOP()に下記のエラーが出ます。 'System.Windows.Forms.WebBrowser' に 'stop' の定義が含まれておらず、型'System.Windows.Forms.WebBrowser' の最初の引数を受け付ける拡張メソッドが見つかりませんでした。using ディレクティブまたはアセンブリ参照が不足しています。 VS2010を使用し、.NETは4なので問題なく使えると思うのですが原因不明です。 以下ソースです。 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace busywait4 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { webBrowser1.Navigate("http://yahoo.co.jp");//もう一度、アクセスしなおす。 } int i; private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { webBrowser1.stop(); }

  • C#プログラムにて

    C#プログラムにて お世話になります。 C#初心者です。 プログラムコードを書き始めで、早速行き 詰っています。 ステップでコードの動きを確認したところ、 program.csのMainから下記のForm1.csに 移りForm1のデザイナが表示されるのですが、 button3を押してもForm3が表れません。 また、ステップの黄色いカーソルと言いますか ステップの位置情報も消えています。 何がどう悪いのか分からなく困っています。 どなたかご親切な方、ご教授頂きたく 宜しくお願い致します。     記 using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace WindowsFormsApplication3 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { } private void button3_Click(object sender, EventArgs e) { Form3 cForm3 = new Form3(); cForm3.ShowDialog(); } private void button2_Click(object sender, EventArgs e) { DialogResult ans; ans = MessageBox.Show("最新のコード表を照会しますか?", "Microsoft Visual Studio", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (ans == DialogResult.OK) Application.Exit(); } private void button12_Click(object sender, EventArgs e) { Form4 cForm4 = new Form4(); cForm4.ShowDialog(); } } }

  • C#で処理中の状況をStatusLabelに表示

    C#で処理中の状況をStatusLabelに表示させたいのですが、どうやらマルチスレッドを使えば良いらしい事は分かったのですが、説明しているページを参考にいろいろやってみたのですがどうもうまくいきません。 例えば次のような場合、10秒後に”9”と表示されて終わってしまうのですが、どの様に書き直せばよろしいでしょうか? すみません、どなたかご存じの方教えていただけないでしょうか。 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Threading; namespace test_multithread3 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { for (int i = 0; i < 10; i++) { toolStripStatusLabel1.Text = i.ToString(); Thread.Sleep(1000); } } } }

  • なぜ、clickイベントが起こってしまうのか? 回避するにはどのように

    なぜ、clickイベントが起こってしまうのか? 回避するにはどのようにしたら? お世話になります。 Visual Studio 2008 C#での開発です。 以下のような簡単なコードでの実験なのですが、 フォームには radioボタン2個とボタンが配置されています。 やりたいことは  1.button1がクリックされたらbutton1自身を使用不可にする  2.radioButton1がクリックされたらbutton1を再度使用可にする です。 しかし、どうもbutton1のクリックイベントの途中でradioButton1の クリックイベントが発生してしまい、思ったような動作になりません。 どのようにしたらbutton1のクリックイベントの途中のradioButton1の クリックイベントの発生を止めることができるのでしょうか? よろしくお願いします。 namespace WindowsFormsApplicationTest { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { Console.WriteLine("1:button1がクリックされました"); Console.WriteLine("2:button1のenabled=" + button1.Enabled); button1.Enabled = false; Console.WriteLine("6:button1のenabled=" + button1.Enabled); } private void radioButton1_Click(object sender, EventArgs e) { Console.WriteLine("3:radioButton1がクリックされました"); Console.WriteLine("4:button1のenabled=" + button1.Enabled); button1.Enabled = true; Console.WriteLine("5:button1のenabled=" + button1.Enabled); } } } 上のコードでの実験結果 1:button1がクリックされました 2:button1のenabled=True 3:radioButton1がクリックされました 4:button1のenabled=False 5:button1のenabled=True 6:button1のenabled=True

専門家に質問してみよう