

backgroundWorkerの中で初期化処理した後に定期処理タスクを起動して画面に進行状況を知らせたいです。初期化処理は問題なく処理できましたが、定期処理タスクが正常に起動できなかった、'System.InvalidOperationException'というエラーが出ました。  
以下は主なソースです  
\---コントローラのInvokeを使って解決出来ました、[ここ](https://stackoverflow.com/questions/206867/what-
is-the-best-way-to-update-form-controls-from-a-worker-thread)を参考しました

メイン画面

[code]

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    namespace BGThread
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
                backgroundWorker1.RunWorkerAsync();
            }
    
            private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
            {
                backgroundWorker1.ReportProgress(0, "start Form init--"); 
                Console.WriteLine("start Form init--");
                Thread.Sleep(5000);
    
                LoopWork lw = new LoopWork(backgroundWorker1);
    
    
            }
    
            private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
            {
                string msg = (string)e.UserState;
                textBox1.Text = msg;
            }
        }
    }
    
[/code]

定期処理タスク

[code]

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace BGThread
    {
        public class LoopWork
        {
            private BackgroundWorker bgWorker;
            public LoopWork(BackgroundWorker bgWorker)
            {
                this.bgWorker = bgWorker;
                init();
            }
    
            private void init()
            {
                task1();
                task2();
            }
    
            private void task1()
            {
                Task.Factory.StartNew(() =>
                {
                    while (true)
                    {
                        bgWorker.ReportProgress(0, "taks1--" + DateTime.Now.ToString("hh:mm:ss"));
                        Console.WriteLine("taks1--" + DateTime.Now.ToString("hh:mm:ss"));
                        Thread.Sleep(new TimeSpan(0, 0, 10));
                    }
                });
            }
            private void task2()
            {
                Task.Factory.StartNew(() =>
                {
                    while (true)
                    {
                        bgWorker.ReportProgress(0, "taks2--" + DateTime.Now.ToString("hh:mm:ss"));
                        Console.WriteLine("taks2--" + DateTime.Now.ToString("hh:mm:ss"));
                        Thread.Sleep(new TimeSpan(0, 0, 15));
                    }
                });
            }
        }
    }
    
[/code]


CC BY-SA 3.0
2016-12-05T06:28:56.623
30919
2017-10-07T02:04:34.320
2017-05-23T12:38:56.083
-1
19819
question
c#
backgroundWorkerで新しいループタスクを起動したい


`BackgroundWorker`クラスはバックグラウンドで長い処理を行うためのものです。行いたい処理を`DoWork`イベントに含めることができます。この`DoWork`イベントが完了した時点で「長い処理」は完了したと見なされ`RunWorkerCompleted`イベントを処理した後、`BackgroundWorker`インスタンスは破棄されます。

今回の例ですと

[code]

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        backgroundWorker1.ReportProgress(0, "start Form init--"); 
        Console.WriteLine("start Form init--");
        Thread.Sleep(5000);
    
        LoopWork lw = new LoopWork(backgroundWorker1);
    }
    
[/code]

この`LoopWork`コンストラクターを呼び出し終わった時点で`BackgroundWorker`は終了しています。`Task.Factory.StartNew()`にて新たなタスクを起動すべきではなく、スレッド内で実行すべきです。


CC BY-SA 3.0
2016-12-05T07:06:23.823
30920
2016-12-05T07:06:23.823
4236
30919
answer