多线程的进度条和代码位置(vb.net)? [英] Multithreading for a progressbar and code locations (vb.net)?

查看:137
本文介绍了多线程的进度条和代码位置(vb.net)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法从其他线程更新进度条. 我确实以最简单的方式运行它,但随后清理代码使我陷入困境.

I am stuck updating a progressbar from a different thread. I did get it running in the simplest way, but then cleaning the code gets me stuck.

我的测试代码看起来像是网络上与backgroundworker和BeginInvoke相关的所有示例.

My testing code looks like all the examples on the web related to backgroundworker and BeginInvoke.

FormP是Progressbar-Form. 这有效:

FormP is the Progressbar-Form. This works:

Public Class Form1
Private Delegate Sub delegate_ProgressUpdate(ByVal paramValue As Integer,
  ByVal paramMax As Integer)

Private Sub Button1_Click(sender As System.Object,
  e As System.EventArgs) Handles Button1.Click
    ' Test 01:
    ' Show Progressbar via BGW
    ' All functions are within Form1
    Dim bgw As New BackgroundWorker()
    AddHandler bgw.DoWork, AddressOf BGW_Sample01_DoWork

    FormP.Show(Me)
    bgw.RunWorkerAsync()
End Sub

Private Sub invokeMe_ProgressUpdate(ByVal paramValue As Integer, ByVal paramMax As Integer)
    FormP.ProgressBar1.Maximum = paramMax
    FormP.ProgressBar1.Value = paramValue
    FormP.ProgressBar1.Update()
End Sub

Private Sub BGW_Sample01_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs)
    For i As Integer = 1 To 10
        Threading.Thread.Sleep(500) ' Test delay
        Me.BeginInvoke(New delegate_ProgressUpdate(AddressOf invokeMe_ProgressUpdate),
                       i, 10)
    Next
    MessageBox.Show("Fertig")
End Sub

如果我尝试使工作更加有序地封装在FormP中,它将无法正常工作.

If I try to make things work more orderly encapsulated in FormP, it doesn't work.

Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
    Dim bgw As New BackgroundWorker
    AddHandler bgw.DoWork, AddressOf BGW_Sample02_DoWork
    FormP.Show(Me)
    bgw.RunWorkerAsync()
End Sub

Private Sub BGW_Sample02_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs)
    For i As Integer = 1 To 10
        Threading.Thread.Sleep(500)
        FormP.SetProgress(i, 10)
    Next
    MessageBox.Show("Fertig")
End Sub


' ########## FormP #################

Public Class FormP

Private Delegate Sub delegate_ProgressUpdate(ByVal value As Integer, ByVal maximum As Integer)

Public Sub SetProgress(ByVal paramValue As Integer, ByVal paramMaximum As Integer)
    If Me.InvokeRequired Then
        Me.Invoke(New delegate_ProgressUpdate(AddressOf Me.SetProgress), paramValue, paramMaximum)
    Else
        Me.ProgressBar1.Maximum = paramMaximum
        Me.ProgressBar1.Value = paramValue
        Me.ProgressBar1.Update()
    End If
End Sub

End Class

FormP不会冻结,但是UI不会更新. 实际上Me.InvokeRequired是错误的,我认为这就是我开始错过一些重要部分的地方. 我在这里尝试了Form1.InvokeRequired,但这也是错误的. 我的理解是:这里的调用线程是bgw线程,无论该线程在什么类代码中调用... 好像不是吗?

FormP does not freeze, but UI is not updated. Actually Me.InvokeRequired is false and I think that's where I begin to miss some important parts. I tried Form1.InvokeRequired here, but it's false as well. My understanding is: the calling thread here is the bgw thread, no matter in what class the code is that this thread calls... That seems not to be it?

感谢您的任何想法.

推荐答案

最终有效的方法:

Private frmP As FormP

Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
    Dim bgw As New BackgroundWorker
    If Me.frmP IsNot Nothing AndAlso Me.frmP.Visible Then Return
    Me.frmP = New FormP
    Me.frmP.Show(Me)
    AddHandler bgw.DoWork, AddressOf BGW_Sample02_DoWork
    bgw.RunWorkerAsync(New Object() {Me.frmP})
End Sub

Private Sub BGW_Sample02_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs)
    Dim objFrmP As FormP = DirectCast(e.Argument(0), FormP)
    For i As Integer = 1 To 10
        objFrmP.setProgress(i, 10)
        Threading.Thread.Sleep(500)
    Next
    MessageBox.Show("Finished")
End Sub

FormP中的进度对话框代码:

The Progress-Dialog-Code in FormP:

Public Sub setProgress(paramValue As Integer, paramMaximum As Integer)
    If Me.InvokeRequired Then
        ' defining a delegate type is not really necessary
        Me.Invoke(Sub() Me.setProgress(paramValue, paramMaximum))
    Else
        Me.ProgressBar1.Maximum = paramMaximum
        Me.ProgressBar1.Value = paramValue
        Me.ProgressBar1.Update()
    End If
End Sub

这篇关于多线程的进度条和代码位置(vb.net)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆