【C# スレッド間の変数アクセスについて】AプロセスとBackgroundWorkerが存在します(下記サンプル参照)。


それぞれが、プログレスバー表示フラグ(もしくはプログレスバー終了フラグ)に対し
書込み・読込を行っています。
この処理がたまに失敗するケースがあるのですが、、、、、、、
(失敗の内容はhttp://q.hatena.ne.jp/1303911980)

プリミティブな変数を同時アクセスすることにより、エラーになるという可能性はあるのでしょうか?

回答者はC#経験有無も答えてください(C#に経験なくてもC言語では、、Javaでは、、、という回答も受け付けております)。

●Aプロセスの処理

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

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

●BackgroundWorkerの処理

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

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

 }
 プログレスバー終了←④
 プログレスバー表示フラグ=true;←⑤
 System.Windows.Forms.Application.DoEvents();

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2011/05/08 18:55:03
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答1件)

id:freemann No.1

回答回数335ベストアンサー獲得回数55

ポイント60pt

コメントがあいてないのでこちらで失礼します。

次のようにBackgroundWorkerのイベントでプログレスバーの更新処理及びログの書き込みを行うのはだめなのでしょうか?


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 ThreadSample
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnClose_Click(object sender, EventArgs e)
        {

            this.Close();
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            BackgroundWorker bkwk = new BackgroundWorker();
            bkwk.DoWork += new DoWorkEventHandler(bkwk_DoWork);
            bkwk.ProgressChanged += new ProgressChangedEventHandler(bkwk_ProgressChanged);
            bkwk.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bkwk_RunWorkerCompleted);
            bkwk.WorkerReportsProgress = true;
            bkwk.RunWorkerAsync(1000000);
            
        }

        void bkwk_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {

            MessageBox.Show("終了しました。");
        }

        void bkwk_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.progressBar1.Value = e.ProgressPercentage;
            this.progressBar1.Invalidate();
        }

        void bkwk_DoWork(object sender, DoWorkEventArgs e)
        {
            double sum = 0d;

            BackgroundWorker bkgk = (BackgroundWorker)sender;

            int a = (int)e.Argument;

            for (int i = 0; i < a; i++)
            {
                for (int j = 0; j < 10000; j++)
                {
                    sum += j;
                }

                    bkgk.ReportProgress(100 * i / a);
            }

        }
    }
}

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません