none
VB.net BackgroundWorker執行一定次數變成前景執行 RRS feed

  • 問題

  • 我寫了一個使用backgroundworker來跑無限迴圈的程式,但是在跑到約100次左右視窗就凍結了

    看起來似乎從背景執行變成前景,於是我設定一個Timer去讀取現在時間來看看是不是這樣,結果還是跑到約100次Timer就自動停止了

    找不到問題點在哪,請大家幫忙 感謝

     Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            If BackgroundWorker1.IsBusy Then
                MessageBox.Show("系統執行中")
            Else
                Chart1.Series(0).Points.Clear()
                Chart1.Series(1).Points.Clear()
                Chart2.Series(0).Points.Clear()
                Chart2.Series(1).Points.Clear()
                Button1.BackColor = Color.YellowGreen
                MistakeCount = 0
                MistakeCount_R = 0
                Timer1.Enabled = True
                BackgroundWorker1.RunWorkerAsync()  '起始背景執行的呼叫
            End If
        End Sub
    
        Private Sub todo_work(ByVal worker As BackgroundWorker, ByVal e As DoWorkEventArgs)
            Dim count As Integer = 0
            While True '無限迴圈
                If worker.CancellationPending Then
                    e.Cancel = True
                    Exit While
                End If
    
                TempValue = Listening_Temp() '執行的程式
                count += 1
                worker.ReportProgress(0)
            End While
        End Sub
    
        Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
            Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
    
            todo_work(worker, e)   '欲背景執行的 function
        End Sub
    
        Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
            Label4.Text = MistakeCount
            Label5.Text = MistakeCount_R
            Chart1.Series(0).Points.AddY(TempValue(0))
            Chart1.Series(1).Points.AddY(TempValue(0))
            Chart2.Series(0).Points.AddY(TempValue(1))
            Chart2.Series(1).Points.AddY(TempValue(1))
            Me.Update() '沒設的話chart1就不更新但chart2正常
        End Sub
    
        Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
            If (e.Error IsNot Nothing) Then
                MessageBox.Show(e.Error.Message)
            ElseIf e.Cancelled Then
                MessageBox.Show("使用者取消執行!")
            Else
                MessageBox.Show("工作完成!")
            End If
        End Sub
        Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    
            Label8.Text = Now.ToString("HH:mm:ss.ffffff")
        End Sub


    • 已編輯 小雞John 2019年8月30日 上午 08:52 錯字
    2019年8月30日 上午 08:51

解答

  •       有試過,看count在畫面停止的時候是有在跑的

    我的想法是這樣,我並不覺得你原來的程式碼會出現多個 backgroundworker,至少看你列出的程式碼沒有這個跡象。

    我反而覺可能是畫面重繪卡住了。

    幾個測試的想法:

    (1) 先把 Chart 的部分註解起來測試看看

    (2) 加入 SuspendLayout .. ResumeLayout 像這樣

    Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
           
            this.SuspendLayout ()
            Label4.Text = MistakeCount
            Label5.Text = MistakeCount_R
            Chart1.Series(0).Points.AddY(TempValue(0))
            Chart1.Series(1).Points.AddY(TempValue(0))
            Chart2.Series(0).Points.AddY(TempValue(1))
            Chart2.Series(1).Points.AddY(TempValue(1))
            this.ResumeLayout()
            '' Me.Update() '沒設的話chart1就不更新但chart2正常
            '' 暫時把 update 註解起來看看
        End Sub
    



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

    • 已標示為解答 小雞John 2019年9月3日 上午 08:16
    2019年9月3日 上午 07:52
    版主

所有回覆

  • 您的BackgroundWorker負責執行的是一個除非被取消, 否則會一直執行的無窮迴圈, 所以當您建立100個BackgroundWorker, 就會有100個無窮迴圈在執行, 視窗凍結的原因並不是變成前景作業, 而是電腦跑不動了
    2019年8月30日 下午 11:07
  • 原來是因為這樣 那如果想要只執行一個無窮迴圈該怎麼修改呢? 求指點
    2019年9月2日 上午 01:25
  • 您的執行緒看起來像是要執行Listening的動作, 如果是這樣的話, 可以由一個執行緒執行在迴圈中Listen的動作, 如果在Listen中接收到Request, 再建立其他的執行緒處理接收到的Request, 意即其他的執行緒不需要也執行在迴圈中Listen的動作
    2019年9月2日 上午 02:04
  • 對的 我是連接一個偵測溫度的裝置 想要一直把偵測的溫度回傳並顯示,

    這樣的話是不是就代表每次都會有Request呢? 另外我有個疑惑是我的一個BackgroundWorker一直執行無窮迴圈沒執行完怎麼會建立下一個BackgroundWorker呢?

    2019年9月2日 上午 02:47
  • 我懷疑是資料抓得太快,導致畫面來不及處理更新。你試著在 while 迴圈中加入一點點的 Thread.Sleep 測試看看。

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

    2019年9月2日 下午 05:12
    版主
  • BackgroundWorker是非同步的作業, 所以前一個BackgroundWorker尚未執行結束前是可以再建立其他的BackgroundWorker的
    2019年9月3日 上午 12:36
  • 我懷疑是資料抓得太快,導致畫面來不及處理更新。你試著在 while 迴圈中加入一點點的 Thread.Sleep 測試看看。

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

         我也有想過這個問題,設了Thread.sleep(100)

         跑了一小時左右還是當了 程式都不動了

         再嘗試Thread.sleep(1000) 跑了十小時左右也不動了

         想讓他一直跑 但是他卻自己停止 看記憶體用量也沒爆 很疑惑怎麼會停了


    2019年9月3日 上午 01:26
  • BackgroundWorker是非同步的作業, 所以前一個BackgroundWorker尚未執行結束前是可以再建立其他的BackgroundWorker的

    了解,原來非同步作業是這個意思,

    我將無窮迴圈拿掉,然後讓BackgroundWorker跑完的時候再執行一次,形成無窮迴圈,這樣子應該可以解決建立好幾個BackgroundWorker的問題嗎?我還加了Dispose 想釋放些空間出來

        Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
            If (e.Error IsNot Nothing) Then
                MessageBox.Show(e.Error.Message)
            ElseIf e.Cancelled Then
                MessageBox.Show("使用者取消執行!")
            Else
                BackgroundWorker1.Dispose()
                BackgroundWorker1.RunWorkerAsync() '再執行一次  BackgroundWorker
            End If
        End Sub


    2019年9月3日 上午 01:35
  • 確認一下,有試著用 Debug.WriteLine 觀察 count 看看在畫面停止的時候,迴圈還有繼續跑嗎 ?


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


    2019年9月3日 上午 03:11
    版主
  • 確認一下,有試著用 Debug.WriteLine 觀察 count 看看在畫面停止的時候,迴圈還有繼續跑嗎 ?


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


          有試過,看count在畫面停止的時候是有在跑的
    2019年9月3日 上午 03:39
  • BackgroundWorker1.Dispose之後BackgroundWorker1就不能用了, 接著呼叫BackgroundWorker1.RunWorkerAsync應該會發生錯誤
    2019年9月3日 上午 07:49
  •       有試過,看count在畫面停止的時候是有在跑的

    我的想法是這樣,我並不覺得你原來的程式碼會出現多個 backgroundworker,至少看你列出的程式碼沒有這個跡象。

    我反而覺可能是畫面重繪卡住了。

    幾個測試的想法:

    (1) 先把 Chart 的部分註解起來測試看看

    (2) 加入 SuspendLayout .. ResumeLayout 像這樣

    Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
           
            this.SuspendLayout ()
            Label4.Text = MistakeCount
            Label5.Text = MistakeCount_R
            Chart1.Series(0).Points.AddY(TempValue(0))
            Chart1.Series(1).Points.AddY(TempValue(0))
            Chart2.Series(0).Points.AddY(TempValue(1))
            Chart2.Series(1).Points.AddY(TempValue(1))
            this.ResumeLayout()
            '' Me.Update() '沒設的話chart1就不更新但chart2正常
            '' 暫時把 update 註解起來看看
        End Sub
    



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

    • 已標示為解答 小雞John 2019年9月3日 上午 08:16
    2019年9月3日 上午 07:52
    版主
  • BackgroundWorker1.Dispose之後BackgroundWorker1就不能用了, 接著呼叫BackgroundWorker1.RunWorkerAsync應該會發生錯誤
          目前執行起來是沒有錯誤耶
    2019年9月3日 上午 08:08
  •       有試過,看count在畫面停止的時候是有在跑的

    我的想法是這樣,我並不覺得你原來的程式碼會出現多個 backgroundworker,至少看你列出的程式碼沒有這個跡象。

    我反而覺可能是畫面重繪卡住了。

    幾個測試的想法:

    (1) 先把 Chart 的部分註解起來測試看看

    (2) 加入 SuspendLayout .. ResumeLayout 像這樣

    Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
           
            this.SuspendLayout ()
            Label4.Text = MistakeCount
            Label5.Text = MistakeCount_R
            Chart1.Series(0).Points.AddY(TempValue(0))
            Chart1.Series(1).Points.AddY(TempValue(0))
            Chart2.Series(0).Points.AddY(TempValue(1))
            Chart2.Series(1).Points.AddY(TempValue(1))
            this.ResumeLayout()
            '' Me.Update() '沒設的話chart1就不更新但chart2正常
            '' 暫時把 update 註解起來看看
        End Sub



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

          太棒了!正常執行了!

          看來如同大大所言是畫面重繪卡住了

          感謝兩位大大指點,受益匪淺

    2019年9月3日 上午 08:16