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

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

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

Re[3]: プログレスバーのマーキーが動かない


(過去ログ 114 を表示中)

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

■67163 / inTopicNo.1)  プログレスバーのマーキーが動かない
  
□投稿者/ げんろく (1回)-(2013/07/08(Mon) 22:13:51)

分類:[C#] 

初めまして。

タイトルのように、メインフォームから呼び出した進捗フォームのマーキータイプのプログレスバーが動きません。
MainWorkは複数の関数を呼び出したりファイルの入出力を行っているため結構重い処理になっています。

原因はどこにあるのかご教授下さい。宜しくお願いします。環境は、.NET2.0C#です。


#メインフォーム
private void button1_Click(object sender, EventArgs e)
{
    ProgressBar pb = new ProgressBar("処理中...",MainWork,"");
    DialogResult result = pb.ShowDialog(this);

    if (result == DialogResult.Cancel)
    {
         //キャンセル処理
    }
    else if (result == DialogResult.OK)
    {
        //OK処理
    }
}


#進捗フォーム
キャンセルボタンとプログレスバーのみ配置しています。

    public partial class ProgressBar : Form
    {
        public ProgressBar (string caption, DoWorkEventHandler doWork, object argument)
        {
            InitializeComponent();
            this.Text = caption;
            this.progressBar.Style = ProgressBarStyle.Marquee;
            this.progressBar.MarqueeAnimationSpeed = 200;
            this.CancelButton = this.cancelAsyncButton;
            this.progressBar.Minimum = 0;
            this.progressBar.Maximum = 100;
            this.cancelAsyncButton.Text = "キャンセル";
            this.cancelAsyncButton.Enabled = true;
            this.backgroundWorker1.WorkerReportsProgress = true;
            this.backgroundWorker1.WorkerSupportsCancellation = true;
            workerArgument = argument;
            //イベント
            this.Shown += new EventHandler(ProgressDialog_Shown);
            this.cancelAsyncButton.Click += new EventHandler(cancelAsyncButton_Click);
            this.backgroundWorker1.DoWork += doWork;
            this.backgroundWorker1.RunWorkerCompleted +=
                new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
        }

        private object workerArgument = null;

        private void ProgressDialog_Shown(object sender, EventArgs e)
        {
            this.backgroundWorker1.RunWorkerAsync(this.workerArgument);
        }

        //キャンセルボタンが押されたとき
        private void cancelAsyncButton_Click(object sender, EventArgs e)
        {
            if (!cancelAsyncButton.Enabled) return;
            DialogResult result = MessageBox.Show("キャンセルしますか?", "処理中", MessageBoxButtons.OKCancel,MessageBoxIcon.Exclamation);
            if (result == DialogResult.OK)
            {
                cancelAsyncButton.Enabled = false;
                backgroundWorker1.CancelAsync();
            }
        }

        //バックグラウンド処理が終了したとき
        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                this.DialogResult = DialogResult.Cancel;
            }
            else
            {
                this._result = e.Result;
                this.DialogResult = DialogResult.OK;
            }
            this.Close();
        }
    }

引用返信 編集キー/
■67164 / inTopicNo.2)  Re[1]: プログレスバーのマーキーが動かない
□投稿者/ 魔界の仮面弁士 (258回)-(2013/07/08(Mon) 22:38:27)
No67163 (げんろく さん) に返信
> マーキータイプのプログレスバーが動きません。

すくなくとも当方では、
void MainWork(object sender, DoWorkEventArgs e) { System.Threading.Thread.Sleep(10000); }
に対して、プログレスバーが作動していました。

Visual Style は有効になっているかを確認してみてください。
(XP のクラシックスタイルなどでは、マーキータイプは動作しません)


> MainWorkは複数の関数を呼び出したりファイルの入出力を行っているため結構重い処理になっています。
MainWork はスレッドセーフになっていますか?


> public partial class ProgressBar : Form
フォーム名も ProgressBar なのでしょうか? 名前空間が異なるとはいえ、
System.Windows.Forms.ProgressBar と競合する名前は混乱の元なので、避けた方が無難かと思います。


> this.progressBar.Style = ProgressBarStyle.Marquee;
Form 名だけでなく、コントロール名も progressBar なのですか?
大文字小文字を混在させたとしても、コントロールに重複する名前を付けるべきではありません。
(この場合、Form と ProgressBar の両方が、"ProgressBar" という名前になります)

重複させても動かないわけではありませんが、Visual Studio のデザイナが解釈できなくなるので、
何か別の名前を付ける事をお奨めします。

> ProgressBar pb = new ProgressBar("処理中...",MainWork,"");
> DialogResult result = pb.ShowDialog(this);
pb を using ブロックで囲みましょう。
ShowDialog で呼び出したフォームは Dispose せねばなりません。


> this._result = e.Result;
this._result とは?
引用返信 編集キー/
■67172 / inTopicNo.3)  Re[2]: プログレスバーのマーキーが動かない
□投稿者/ げんろく (2回)-(2013/07/10(Wed) 15:01:34)
No67164 (魔界の仮面弁士 さん) に返信
> ■No67163 (げんろく さん) に返信
>>マーキータイプのプログレスバーが動きません。
> 
> すくなくとも当方では、
> void MainWork(object sender, DoWorkEventArgs e) { System.Threading.Thread.Sleep(10000); }
> に対して、プログレスバーが作動していました。
> 
> Visual Style は有効になっているかを確認してみてください。
> (XP のクラシックスタイルなどでは、マーキータイプは動作しません)
> 

そのMainWorkに変更したら私のほうでも動作しました。

> 
>>MainWorkは複数の関数を呼び出したりファイルの入出力を行っているため結構重い処理になっています。
> MainWork はスレッドセーフになっていますか?
> 

スレッドセーフ・・・ここかもしれません。
あまり理解していないのですが・・・(すいません、結構初心者なもので。。)
フォーム上のコントロールを操作しない場合でも関係ありますか?


> 
>>public partial class ProgressBar : Form
> フォーム名も ProgressBar なのでしょうか? 名前空間が異なるとはいえ、
> System.Windows.Forms.ProgressBar と競合する名前は混乱の元なので、避けた方が無難かと思います。
> 
> 
>> this.progressBar.Style = ProgressBarStyle.Marquee;
> Form 名だけでなく、コントロール名も progressBar なのですか?
> 大文字小文字を混在させたとしても、コントロールに重複する名前を付けるべきではありません。
> (この場合、Form と ProgressBar の両方が、"ProgressBar" という名前になります)
> 
> 重複させても動かないわけではありませんが、Visual Studio のデザイナが解釈できなくなるので、
> 何か別の名前を付ける事をお奨めします。
> 
>>    ProgressBar pb = new ProgressBar("処理中...",MainWork,"");
>>    DialogResult result = pb.ShowDialog(this);
> pb を using ブロックで囲みましょう。
> ShowDialog で呼び出したフォームは Dispose せねばなりません。

ありがとうございます。ここ気をつけます。

> 
> 
>>this._result = e.Result;
> this._result とは?

特に気にしないで下さい。

引用返信 編集キー/
■67177 / inTopicNo.4)  Re[3]: プログレスバーのマーキーが動かない
□投稿者/ Azulean (178回)-(2013/07/10(Wed) 23:33:26)
No67172 (げんろく さん) に返信
> そのMainWorkに変更したら私のほうでも動作しました。

だとすると、問題の MainWork がメインスレッドに処理を委譲している可能性が考えられます。
最初の方で Invoke を呼んでしまっていて、ほとんどの処理がメインスレッドで実行されていると言うことはありますか?
または、COM や ActiveX を使っていて、知らないうちにメインスレッドに処理が委譲されていることはないでしょうか?

前述のような兆候が見つからない場合は、重い処理のいくつかの場所でブレークポイントを設定して、呼び出し履歴の下の方が Program.Main といったメインスレッドを示すような履歴になっている場合は、どこかでメインスレッドに処理を委譲してしまっています。
呼び出し履歴をもう少し確認すると、どこからかを特定できることがあります。

ブレークポイントがうまく設定できない場合は、プログレスバーが更新されない間に、Visual Studio の デバッグ - すべて中断 を選ぶと、実行中の処理を一時停止して呼び出し履歴などを確認できますので、何がどのスレッドで実行されているか確認してみるのも手でしょう。
引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -