人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

【解決は500?1000ポイント:C#のプロセス間処理】
AプロセスとBackgroundWorkerが存在します。
AプロセスはBackgroundWorkerにプログレスバー表示を依頼し、
その後、処理が完了した段階でBackgroundWorkerにプログレスバー終了依頼を出します。
このとき、
Aプロセスでは以下のようにプログレスバーの終了を待ち受けます。


while(プログレスバー表示フラグ==true){
System.Windows.Forms.Application.DoEvents();
log.write("注意:プログレスバー表示中");
}

BackgroundWorkerでBoolean型のプログレスバー表示フラグをfalseに
しているのですが、Aプロセスのループから抜けません。
BackgroundWorkerが終了したことを伝えループを終える良い解決方法はありませんか?

●質問者: harunoharuno
●カテゴリ:コンピュータ インターネット
✍キーワード:application C# Windows Write フラグ
○ 状態 :終了
└ 回答数 : 4/4件

▽最新の回答へ

1 ● きゃづみぃ
●100ポイント

グローバルの変数で プログレスバーが 終了したら フラグを 立てるようにする。

その変数を 質問の中のループで チェックして フラグが たってたら 抜けるようにしてやればいいでしょう。


または、そのループ内で プログレスバーが終了したか どうか(たぶん 100%)かどうかを

チェックして 終了したら 抜ければいいでしょう。

◎質問者からの返答

回答ありがとうございます。

現在、プログレスバーを終了するタイミングでBoolean型のプログレスバー表示フラグをfalseに

しています。このプログレスバー表示フラグはAプロセスが管理する変数なので

ともにアクセスできるグローバルなエリアにフラグを設けて確かめます。


2 ● くじぇ
●100ポイント

処理は、Aプロセスで行っているのでしょうか、それともBackgroundWorkerで行っているのでしょうか?

私ならAプロセスの中に処理を組み込み、BackgroundWorkerはプログレスバーの表示に集中させます。

そしてAプロセスが終わり次第、AプロセスからBackgroundWorkerには表示を終了するよう指示させます。

つまり

while(プログレスバー表示フラグ==true){

System.Windows.Forms.Application.DoEvents();

log.write("注意:プログレスバー表示中");

処理

if(処理終了==true){ プログレスバー表示フラグ=false; }

}

プログレスバーの後片付け

という感じです。

◎質問者からの返答

回答ありがとうございます。

>>処理は、Aプロセスで行っているのでしょうか、それともBackgroundWorkerで行っているのでしょうか?

>>私ならAプロセスの中に処理を組み込み、BackgroundWorkerはプログレスバーの表示に集中させます。

>>そしてAプロセスが終わり次第、AプロセスからBackgroundWorkerには表示を終了するよう指示させます。


現状次のようになっています。

●Aプロセスの処理

プログレスバー終了フラグ=true; ←?

while(プログレスバー表示フラグ==true){

System.Windows.Forms.Application.DoEvents();

log.write("注意:プログレスバー表示中");←?

}

log.write("処理完了");←?



●BackgroundWorkerの処理



while(プログレスバー終了フラグ){

log.write("進捗表示");←?

}

プログレスバー終了←?

プログレスバー表示フラグ=true;←?

System.Windows.Forms.Application.DoEvents();


1?6の順序で処理が流れてほしいのですが、?のループから抜け出せません。

この原因についてもご回答いただきたいです。


3 ● Galapagos
●50ポイント

ご存じかと思いますが、Windowsの場合、プロセス間の値のやり取りはレジストリを介して行います。

その「プログレスバー表示フラグ」というのはレジストリ変数になっていますか?

ご確認ください。


参考 「レジストリの値を取得するには?


4 ● heke2mee
●1000ポイント ベストアンサー

サンプルを作ってみました。

フォーム上にプログレスバーとボタンを配置してください

プログレスバー progressBar1

ボタン button1


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace TestThreading
{
 public partial class Form1 : Form
 {
 private BackgroundWorker bgWorker;
 delegate void dlgProgress(int percentage);
 bool wait = false;

 public Form1()
 {
 InitializeComponent();
 bgWorker = new BackgroundWorker();
 bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
 bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_RunWorkerCompleted);
 }



 private void button1_Click(object sender, EventArgs e)
 {
 this.progressBar1.Value = 0;
 this.button1.Enabled = false;

 bgWorker.RunWorkerAsync();

 wait = true;
 while (wait)
 {
 Application.DoEvents();
 }
 this.button1.Enabled = true;
 }

 void bgWorker_DoWork(object sender, DoWorkEventArgs e)
 {
 //時間のかかる処理
 for (int i = 0; i < 10; i++)
 {
 System.Threading.Thread.Sleep(100);
 int percentage = 10 * (i + 1);

 progressBarUpdate(percentage);
 }
 }

 void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
 {
 wait = false;
 }


 /// <summary>
 /// プログレスバーの更新
 /// </summary>
 public void progressBarUpdate(int percentage)
 {
 if (!(this.IsHandleCreated))
 {
 return;
 }
 MethodInvoker process =
 (MethodInvoker)delegate()
 {
 if (this.progressBar1.Maximum > percentage)
 this.progressBar1.Value = percentage;
 else
 this.progressBar1.Value = 100;
 };
 if (this.InvokeRequired)
 {
 this.Invoke(process);
 }
 else
 {
 process.Invoke();
 }

 }

 private void Form1_FormClosed(object sender, FormClosedEventArgs e)
 {
 bgWorker.DoWork -= new DoWorkEventHandler(bgWorker_DoWork);
 bgWorker.RunWorkerCompleted -= new RunWorkerCompletedEventHandler(bgWorker_RunWorkerCompleted);

 bgWorker.Dispose();
 bgWorker = null;
 }
 }

}

◎質問者からの返答

回答ありがとうございます。

回答いただいたサンプルソースは大体私のソースと類似しています。

残念ながらまだ問題は解決していませんが、解ったことがございましたので

追記します。


Aプロセスで以下のようにコーディングした場合


this.progressBar1.Value = 0;

this.button1.Enabled = false;

bgWorker.RunWorkerAsync();

wait = true;

while (wait)

{

log.Write("test") ←?

Application.DoEvents();

}


?で出力しているログが1回しか記録されません。

Application.DoEventsイベント後に、While文が動いていないように

思えるのですが、いまだ原因は不明です。


なお、現状のコーディングでも10回操作すれば8回ほど

期待通りの動作をすることを確認しています。

たまに、

ループのフラグがFalseになったのにも関わらず抜け出さないことがあるようです。

ご助言宜しくお願いします。

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ