• 締切済み

BackgroundWorkerと同期 VB2008 VB2005

VB2008で、BackgroundWorkerを使って重たい処理をさせています。 DoWork内で、ReportProgress(パーセント値)を呼び出して ProgressChangedメソッドで、そのときの状態を表示させています。ぷプログレスバーだけでなく、あらかじめ作成したデータをTextBoxに情報を表示させています。 しかし、ReportProgress(パーセント値)の後にSystem.Threading.Thread.Sleep(200)を入れないと、たまに ProgressChangedの中のTextBoxを表示させる処理が実行されなくなります。 ReportProgress(パーセント値)の後に同期をとる処理はSleep以外に何かあるのでしょうか? BackgroundWorkerの同期について詳しく書かれている本も探しています。

  • bootx
  • お礼率4% (3/70)

みんなの回答

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

そうですね Application.DoEvents() あたりでしょうか ReportProgressを呼び出す頻度が多すぎるのではないでしょうか?

関連するQ&A

  • VB2005 BackgroundWorkerの使用

    お世話になります。 VB2005のBackgroundWorkerを指定した数だけ使用したいのですが エラーメッセージが以下のように表示されます。 ---------------------------------------------- BackgroundWorker は現在ビジー状態であるため、 複数のタスクを同時に実行できません。 ---------------------------------------------- コーディングは ~FormLoad~ BackgroundWorker1.RunWorkerAsync() BackgroundWorker1.RunWorkerAsync() この部分はFor文で指定しただけ実行したいと考えてます ~DoWork~ Console.Write("DoWork" & vbCrLf) ~RunWorkerCompleted~ Console.Write("RunWorkerCompleted" & vbCrLf) と、しております。 どのようなコーディングを行えば複数実行することが 可能なのでしょうか? よろしくお願いします。

  • BackgroundWorkerの処理

    マルチスレッド機能であるBackgroundWorkerを利用してプログラムを書いていたのですが DoWorkからコントロールへのアクセスが出来ません。 どうすればコントロールへアクセスできるのでしょうか? 誰かお詳しい方、ご教授願います。 Private Sub back1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles back1.DoWork     textbox1.text="処理中とか表示したい" End Sub

  • 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を使うように書かれているものも見ましたが 薦めている理由も知りたいです。

  • VB2008で

    VB2008で System.Threading.Thread.Sleepを使って5秒後にテキストボックスにaと表示させるプログラムを作ろうとしましたが、うまくいなないため、タイマーコントロールを使用したいと思ったのですが、どのようにしたらいいでしょうか?

  • メソッドの処理の同期化

    いつもお世話になっています。 メソッド処理の同期化についてなのですが、 いろいろ調べてみたのですが、いまいちうまく実行できません。 ソースを考えてみたのですが、どこがどう悪いのかご指摘お願いできますでしょうか? 以下のクラスがある場合で public void Add(){ synchronized(this){ System.out.println("待機しています!"); //おそらくここら辺にwait()/notify()処理が来るきがする //同期中に行わない処理をここに記載する? } System.out.println("Addメソッド実行しました"): } public void Change(){ synchronized(this) { //おそらくここら辺にwait()/notify()処理が来るきがする //同期中に行わない処理をここに記載する? //一時停止 処理時間をずらすためループを使用 try { for(int a=0;a<3;a++){ System.out.println("a="+a); Thread.sleep(10000); } }catch (InterruptedException e) { } System.out.println("Changeメソッド完了です"); } } このとき、Add対Change/Add対Addといった形で同期化処理をしたいのですが、どうしてもうまくできません。 仮にThreadを使用して実行してみようとしたのですが、 順番に実行されてしまいます。 したいのが、 1.Addメソッド実行 2・Addメソッド実行 この場合、現状だと a=0 a=0 a=1 a=1 a=2 a=2  と表示されてしまうので、 a=0 a=1 a=2 a=0 a=1 a=2  と表示することはできるのでしょうか? 原因として、wait()/notify()が記載されていないことが影響していると思うのですが。 宜しくお願いします。

  • .NetのBackgroundWorkerクラスについての質問です。

    .NetのBackgroundWorkerクラスについての質問です。 BackgroundWorkerクラスなるものを知るまでは、Threadクラス等でマルチスレッドを実装していました。 MSDNを読みながら、実装自体は非常に簡単に出来ましたが、このバックグラウンドスレッドとは如何なるものなのでしょうか。 フォアグラウンド/バックグラウンドタスクであるならば、CPU優先度(占有度)により、その実行タイミングが左右されるのは容易に想像できるのですが、バックグラウンドスレッドは、どのようにCPU優先度が決まるのでしょうか。(デスクトップWindowsでは、あまり機会がないかとは思いますが、リアルタイムな処理,クリティカルな処理を同クラスによって実装していいのか判断できませんでした。) Formクラスから生成されるということは、Formウィンドウのメッセージスレッドをフォアグラウンドスレッドとし、そのバックグラウンドスレッドといった関係になるのでしょうか。(Formウィンドウのアイドル時間にバックグラウンドスレッドが実行されるという理解であっていますでしょうか。) また、スレッド内でのsleep()呼出しで、スレッドは別スレッドに制御が切り替わるハズだったと思いますが、バックグラウンドスレッド内でThread::Sleep()呼出しをした場合、必ず、フォアグラウンドスレッドに制御が移り、フォアグラウンドスレッドのアイドル時間が発生するまで、バックグラウンドスレッドへ制御が戻ることがないということでしょか。(各スレッドへいつ制御が移るのか分かりませんでした。) ご回答、または、参考サイト,参考文献等、教えてくださると非常に助かります。

  • C# or VB プログレスバー

    プログレスバーで進行状況を表示する処理を入れています。 http://dobon.net/vb/dotnet/programing/progressdialog.html 上記のサイトをパクってとりあえず作ってみました。きちんとできているのですが 1つだけ問題があって try { ProgressDialog pd = new ProgressDialog(); //ダイアログのタイトルを設定 pd.Title = "カウントアップ"; //プログレスバーの最小値を設定 pd.Minimum = 0; //プログレスバーの最大値を設定 pd.Maximum = 10; //プログレスバーの初期値を設定 pd.Value = 0; //進行状況ダイアログを表示する pd.Show(this); //処理を開始 for (int i = 1; i <= 10; i++) { //プログレスバーの値を変更する pd.Value = i; //メッセージを変更する pd.Message = i.ToString() + "番目を処理中..."; //キャンセルされた時はループを抜ける if (pd.Canceled) break; //1秒間待機する(本来なら何らかの処理を行う) System.Threading.Thread.Sleep(1000); } //ダイアログを閉じる pd.Close(); } catch { MessageBox.Show("error"); } こんな感じで使い、プログレスバー表示中に例外が走るとMessageBoxがモーダレスで 表示されてしまいます。プログレスバー表示前だとモーダルのままです。 色々調べたところ原因は裏でスレッドが走っているからだと思います。たぶん・・ ところが対処法となると少々困っています。モーダルでMessageBoxを表示させたいのですが どうすればよいのでしょうか?教えてください。

  • 非同期プログラミングは必ずマルチスレッド?

    非同期プログラミングは必ずマルチスレッドプログラミングになりますか? ここでいう非同期プログラミングとは、 何かのメソッドを実行してその処理(処理Aとする)の結果を待たずに次の処理Bを実行できて、処理Aが終わったらコールバックやデリゲートで、あらかじめ決められたメソッド(finishとする)が呼ばれるといったものです。 処理Aを実行するメソッドを呼ぶ ↓ すぐに処理Bを実行開始(このときバックグラウンドで処理Aが走っている) ↓ 処理Aが終了したのでfinishメソッドが実行される 例えば、Objective-CのNSURLConnectionで非同期通信するときのようなやつです。 こういった非同期プログラミングは、必ずマルチスレッドを使うことになりますか? 普通、別スレッドで処理させるときはスレッド用のライブラリを使うなどして明示的にマルチスレッドプログラミングをしますが、上のように非同期のメソッドを使うと、その裏で自動的に別のスレッドが動くのでしょうか。 それとも、単一スレッドのみで、非同期プログラミングできるでしょうか。 なお、特殊な言語やOSによっては、いくらでも可能性があると思いますので、 メジャーな環境(Windowsや、スマホ) のみに限定してお願いします。言語で言うと、C、C++、Objective-C、Javaあたり。 また、上の「処理A」が終わったとき、メソッド「finish」が呼ばれるとすると、 処理Bの実行中にどのようなタイミングでfinishが呼ばれるのでしょうか。 処理Bはどのような形でfinishに切り替わるのでしょうか。いきなりfinishに処理を奪い取られるのでしょうか

  • VB2010で時間のかかる処理をする場合

    vb2010で開発しています。 時間のかかる処理をするのに、プログレスバーやアニメーションgifを使って 処理をしていることをユーザ側に知らせたいのですが、うまくいきません。 BackgroundWorkerという機能を使うというのはネットで調べたのでが、 それはLOOP等で繰り返し行う処理の場合はできそうなのですが、 今回はSQLSERVERに対して、DELETEやUPDATEを実行したいのです。 SQLを発行するのは一回なのですが、データ量が多いために時間がかかります。 それをうまく処理できる方法はありませんか?

  • VC++

    フォームアプリを作成しており、実装に関して不明点があるため質問させて頂きます。 やりたいこととしては、Formでないファイル(クラス)でFormのコンポーネントを 操作したいことです。 具体的に、重たい処理を別スレッドで処理させて、処理中の経過をFormの プログレスバーに表示することです。 重たい処理は別ファイル(クラス)で行います。 以下に大まかなコードを記載します。 ----------------------------------------------------- ---- Form.h ---- #include "Main.h" namespace XXX { public ref class Form1 : public System::Windows::Forms::Form {  Main^ mMain;    // ボタン押下  private: System::Void btn_Click(System::Object^ sender, System::EventArgs^ e) {   backgroundWorker1->RunWorkerAsync();  }  // ワーカ  private: System::Void backgroundWorker1_DoWork(System::Object^ sender, System::ComponentModel::DoWorkEventArgs^ e) {   mMain->func();    } }; } ---- Main.c ---- Main::func() {  // 処理をしつつプログレスバーのValueを更新 } ----------------------------------------------------- 重たい処理をForm内で処理するのであればデリゲートを使用すれば出来そうです。 上記のようなケースでも適用できますか? また、別の方法があれば教えてください。

専門家に質問してみよう