none
兩個以上backgroundworker會有一個不正確執行 RRS feed

  • 問題

  • 請教一下各位

    當我在winform有兩個backgroundworker的時候,如果在form_load的時候兩個backgroundworker一起動作,在把資料加到datagridwiew的時候,值就不會跟offsetI遞增走,可能會跳號,或是直接就跑到最終值

    如果把backworkerUpdate這個先註解掉,值帶入datagridwiew的時候就會正常

    這是因為什麼原因?是因為兩個backgroundworker的關係嗎?

    private void MAIN_Load(object sender, EventArgs e)
    {         
          backworkerOffsetcreat.RunWorkerAsync();            
          backworkerUpdate.RunWorkerAsync();

    }

    int Enum, Mnum;

    private void backworkerUpdate_DoWork(object sender, DoWorkEventArgs e)
    {

          while (true)
          {
                Focas1.cnc_allclibhndl3(strip, 8193, 5, out cncHandle);                
                Focas1.ODBPRO rdprgnum = new Focas1.ODBPRO();
                Focas1.cnc_rdprgnum(cncHandle, rdprgnum);
                Enum = rdprgnum.data;
                Mnum = rdprgnum.mdata;

                backworkerUpdate.ReportProgress(0);
                Thread.Sleep(1000);

          }

    }

    private void backworkerUpdate_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
          mastxtboxproEnum.Text = "O" + Enum.ToString("d4");
          mastxtboxproMnum.Text = "O" + Mnum.ToString("d4");

    }


    short offsetI;
    float offsetLg, offsetLw, offsetRg, offsetRw;

    private void backworkerToolcreat_DoWork(object sender, DoWorkEventArgs e)
    {

          Focas1.cnc_allclibhndl3(strip, 8193, 5, out cncHandle);
          Focas1.ODBTLINF ODBTLINF = new Focas1.ODBTLINF();
          Focas1.cnc_rdtofsinfo(cncHandle, ODBTLINF);
          Focas1.ODBTOFS ODBTOFSlg = new Focas1.ODBTOFS();
          Focas1.ODBTOFS ODBTOFSlw = new Focas1.ODBTOFS();
          Focas1.ODBTOFS ODBTOFSrg = new Focas1.ODBTOFS();
          Focas1.ODBTOFS ODBTOFSrw = new Focas1.ODBTOFS();

                    

          for (short i = 1; i <= ODBTLINF.use_no; i++)
          {                
                Focas1.cnc_rdtofs(cncHandle, i, 3, 8, ODBTOFSlg);                
                Focas1.cnc_rdtofs(cncHandle, i, 2, 8, ODBTOFSlw);                
                Focas1.cnc_rdtofs(cncHandle, i, 1, 8, ODBTOFSrg);                
                Focas1.cnc_rdtofs(cncHandle, i, 0, 8, ODBTOFSrw);                

                offsetI = i;
                offsetLg = ODBTOFSlg.data / 1000;
                offsetLw = ODBTOFSlw.data / 1000;
                offsetRg = ODBTOFSrg.data / 1000;
                offsetRw = ODBTOFSrw.data / 1000;

                backworkerOffsetcreat.ReportProgress(0);

          }

    }

    private void backworkerOffsetcreat_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {          
          DataGridViewRowCollection rowOffset = datagridviewOffset.Rows;
          rowOffset.Add(new Object[] { offsetI, offsetLg, offsetLw, offsetRg, offsetRw });
    }



    • 已編輯 魏高個 2016年5月31日 上午 01:51
    2016年5月31日 上午 01:46

解答

  • 看起來是兩個執行緒同時在處理同一個資料來源, 這時就要用鎖定的方式控制住資料源

    執行緒同步處理 (C# 和 Visual Basic)


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。


    2016年5月31日 上午 07:40
    版主
  • 看起來是兩個執行緒同時在處理同一個資料來源, 這時就要用鎖定的方式控制住資料源

    執行緒同步處理 (C# 和 Visual Basic)


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。


    謝謝BILL的指教,我研究了一下MSDN的文件作了以下的更改,程式在建立datagridview的時候就可以正常了

    以下提供我完成的程式碼供有類似問題的人參考

    private System.Object lockThisOne = new System.Object();

    private void MAIN_Load(object sender, EventArgs e)
    {         
          backworkerOffsetcreat.RunWorkerAsync();            
          backworkerUpdate.RunWorkerAsync();

    }

    int Enum, Mnum;

    private void backworkerUpdate_DoWork(object sender, DoWorkEventArgs e)
    {

          lock(lockThisOne)

          {

                while (true)
                {
                      Focas1.cnc_allclibhndl3(strip, 8193, 5, out cncHandle);                
                      Focas1.ODBPRO rdprgnum = new Focas1.ODBPRO();
                      Focas1.cnc_rdprgnum(cncHandle, rdprgnum);
                      Enum = rdprgnum.data;
                      Mnum = rdprgnum.mdata;

                      backworkerUpdate.ReportProgress(0);
                      Thread.Sleep(1000);

                }

          }

    }

    private void backworkerUpdate_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
          mastxtboxproEnum.Text = "O" + Enum.ToString("d4");
          mastxtboxproMnum.Text = "O" + Mnum.ToString("d4");

    }

    short offsetI;
    float offsetLg, offsetLw, offsetRg, offsetRw;

    private void backworkerToolcreat_DoWork(object sender, DoWorkEventArgs e)
    {

          lock(lockThisOne)

          {

                Focas1.cnc_allclibhndl3(strip, 8193, 5, out cncHandle);
                Focas1.ODBTLINF ODBTLINF = new Focas1.ODBTLINF();
                Focas1.cnc_rdtofsinfo(cncHandle, ODBTLINF);
                Focas1.ODBTOFS ODBTOFSlg = new Focas1.ODBTOFS();
                Focas1.ODBTOFS ODBTOFSlw = new Focas1.ODBTOFS();
                Focas1.ODBTOFS ODBTOFSrg = new Focas1.ODBTOFS();
                Focas1.ODBTOFS ODBTOFSrw = new Focas1.ODBTOFS();

                    

                for (short i = 1; i <= ODBTLINF.use_no; i++)
                {                
                      Focas1.cnc_rdtofs(cncHandle, i, 3, 8, ODBTOFSlg);                
                      Focas1.cnc_rdtofs(cncHandle, i, 2, 8, ODBTOFSlw);                
                      Focas1.cnc_rdtofs(cncHandle, i, 1, 8, ODBTOFSrg);                
                      Focas1.cnc_rdtofs(cncHandle, i, 0, 8, ODBTOFSrw);                

                      offsetI = i;
                      offsetLg = ODBTOFSlg.data / 1000;
                      offsetLw = ODBTOFSlw.data / 1000;
                      offsetRg = ODBTOFSrg.data / 1000;
                      offsetRw = ODBTOFSrw.data / 1000;

                      backworkerOffsetcreat.ReportProgress(0);

                }

          }

    }

    private void backworkerOffsetcreat_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {          
          DataGridViewRowCollection rowOffset = datagridviewOffset.Rows;
          rowOffset.Add(new Object[] { offsetI, offsetLg, offsetLw, offsetRg, offsetRw });
    }

    • 已標示為解答 魏高個 2016年6月1日 上午 03:24
    2016年6月1日 上午 03:24

所有回覆

  • 兩個 BackgroundWorker 如果是有關聯 (例如 B 會依賴 A 的資料才能做事),如果你沒有一個 A <-> B 之間的溝通管道,那對方怎麼知道要參照誰的資料哩?


    強力監督SQL Injection問題!!

      • 小朱的技術隨手寫:http://www.dotblogs.com.tw/regionbbs/
      • 雲端學堂Facebook: http://www.facebook.com/studyazure

    2016年5月31日 上午 02:09
    版主
  • 兩個 BackgroundWorker 如果是有關聯 (例如 B 會依賴 A 的資料才能做事),如果你沒有一個 A <-> B 之間的溝通管道,那對方怎麼知道要參照誰的資料哩?


    強力監督SQL Injection問題!!

      • 小朱的技術隨手寫:http://www.dotblogs.com.tw/regionbbs/
      • 雲端學堂Facebook: http://www.facebook.com/studyazure

    他們之間是沒有關聯的,一個是負責持續更新資訊,一個是把表格資料帶完就結束,如果是這樣還要給他們關聯嗎?

    2016年5月31日 上午 02:18
  • 您可以在backworkerToolcreat_DoWork的for迴圈加入:

    Thread.Sleep(1);

    再試看看

    2016年5月31日 上午 02:39
  • 您可以在backworkerToolcreat_DoWork的for迴圈加入:

    Thread.Sleep(1);

    再試看看

    謝謝你的回答,感覺有好點,不過還是會有跳號的情形

    加之前是這樣

    加之後變這樣

    2016年5月31日 上午 02:48
  • 看起來是兩個執行緒同時在處理同一個資料來源, 這時就要用鎖定的方式控制住資料源

    執行緒同步處理 (C# 和 Visual Basic)


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。


    2016年5月31日 上午 07:40
    版主
  • 存取同一個 source 還說沒關聯...

    強力監督SQL Injection問題!!

      • 小朱的技術隨手寫:http://www.dotblogs.com.tw/regionbbs/
      • 雲端學堂Facebook: http://www.facebook.com/studyazure

    2016年5月31日 上午 08:01
    版主
  • 看起來是兩個執行緒同時在處理同一個資料來源, 這時就要用鎖定的方式控制住資料源

    執行緒同步處理 (C# 和 Visual Basic)


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。


    謝謝BILL的指教,我研究了一下MSDN的文件作了以下的更改,程式在建立datagridview的時候就可以正常了

    以下提供我完成的程式碼供有類似問題的人參考

    private System.Object lockThisOne = new System.Object();

    private void MAIN_Load(object sender, EventArgs e)
    {         
          backworkerOffsetcreat.RunWorkerAsync();            
          backworkerUpdate.RunWorkerAsync();

    }

    int Enum, Mnum;

    private void backworkerUpdate_DoWork(object sender, DoWorkEventArgs e)
    {

          lock(lockThisOne)

          {

                while (true)
                {
                      Focas1.cnc_allclibhndl3(strip, 8193, 5, out cncHandle);                
                      Focas1.ODBPRO rdprgnum = new Focas1.ODBPRO();
                      Focas1.cnc_rdprgnum(cncHandle, rdprgnum);
                      Enum = rdprgnum.data;
                      Mnum = rdprgnum.mdata;

                      backworkerUpdate.ReportProgress(0);
                      Thread.Sleep(1000);

                }

          }

    }

    private void backworkerUpdate_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
          mastxtboxproEnum.Text = "O" + Enum.ToString("d4");
          mastxtboxproMnum.Text = "O" + Mnum.ToString("d4");

    }

    short offsetI;
    float offsetLg, offsetLw, offsetRg, offsetRw;

    private void backworkerToolcreat_DoWork(object sender, DoWorkEventArgs e)
    {

          lock(lockThisOne)

          {

                Focas1.cnc_allclibhndl3(strip, 8193, 5, out cncHandle);
                Focas1.ODBTLINF ODBTLINF = new Focas1.ODBTLINF();
                Focas1.cnc_rdtofsinfo(cncHandle, ODBTLINF);
                Focas1.ODBTOFS ODBTOFSlg = new Focas1.ODBTOFS();
                Focas1.ODBTOFS ODBTOFSlw = new Focas1.ODBTOFS();
                Focas1.ODBTOFS ODBTOFSrg = new Focas1.ODBTOFS();
                Focas1.ODBTOFS ODBTOFSrw = new Focas1.ODBTOFS();

                    

                for (short i = 1; i <= ODBTLINF.use_no; i++)
                {                
                      Focas1.cnc_rdtofs(cncHandle, i, 3, 8, ODBTOFSlg);                
                      Focas1.cnc_rdtofs(cncHandle, i, 2, 8, ODBTOFSlw);                
                      Focas1.cnc_rdtofs(cncHandle, i, 1, 8, ODBTOFSrg);                
                      Focas1.cnc_rdtofs(cncHandle, i, 0, 8, ODBTOFSrw);                

                      offsetI = i;
                      offsetLg = ODBTOFSlg.data / 1000;
                      offsetLw = ODBTOFSlw.data / 1000;
                      offsetRg = ODBTOFSrg.data / 1000;
                      offsetRw = ODBTOFSrw.data / 1000;

                      backworkerOffsetcreat.ReportProgress(0);

                }

          }

    }

    private void backworkerOffsetcreat_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {          
          DataGridViewRowCollection rowOffset = datagridviewOffset.Rows;
          rowOffset.Add(new Object[] { offsetI, offsetLg, offsetLw, offsetRg, offsetRw });
    }

    • 已標示為解答 魏高個 2016年6月1日 上午 03:24
    2016年6月1日 上午 03:24
  • 存取同一個 source 還說沒關聯...

    強力監督SQL Injection問題!!

      • 小朱的技術隨手寫:http://www.dotblogs.com.tw/regionbbs/
      • 雲端學堂Facebook: http://www.facebook.com/studyazure

    不好意思,一開始沒搞懂,以為沒關聯,謝謝小朱的指導

    2016年6月1日 上午 03:25