Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
VB.NET progressbar backgroundworker_Vb.net_Progress Bar_Backgroundworker - Fatal编程技术网

VB.NET progressbar backgroundworker

VB.NET progressbar backgroundworker,vb.net,progress-bar,backgroundworker,Vb.net,Progress Bar,Backgroundworker,当我的应用程序启动并且刚刚升级时,我正在进行本地数据库更新(sqlite) 是这样的: 用户启动我的应用程序,然后我开始升级过程。 在此升级过程中,我将显示一个具有连续进度条的表单。 升级过程完成后,此表单关闭,用户可以开始使用我的应用程序 但是progressbar不会动画,因为升级过程非常密集 在我的旧VB6版本中,我使用了一个ActiveX Exe,它有一个表单并显示一个进度条。这是我的“背景工作者” 我不确定我是否可以在VB.NET中使用相同的方法 我只看到了在后台工作程序中进行工作的示

当我的应用程序启动并且刚刚升级时,我正在进行本地数据库更新(sqlite)

是这样的: 用户启动我的应用程序,然后我开始升级过程。 在此升级过程中,我将显示一个具有连续进度条的表单。 升级过程完成后,此表单关闭,用户可以开始使用我的应用程序

但是progressbar不会动画,因为升级过程非常密集

在我的旧VB6版本中,我使用了一个ActiveX Exe,它有一个表单并显示一个进度条。这是我的“背景工作者”

我不确定我是否可以在VB.NET中使用相同的方法

我只看到了在后台工作程序中进行工作的示例,但我没有看到任何progressbar本身是后台工作程序的示例

数据库升级需要被阻止,在数据库升级完成之前,用户可能不会使用我的应用程序。这意味着只有progressbar应该“退出进程”,而不是升级


多谢各位

您可以在后台工作线程中引发事件,然后更新UI线程上的进度条。您可以在类中引发事件并在窗体中处理它们。当它们被引发时,您可以在后台工作进程上调用reportprogress()

更多信息:


根据您的要求,我认为您正在寻找:

Application.DoAction()
我在一个应用程序中体验到,需要从xml中加载2000到3000项相关细节,而实现的流程正在逐个读取项,这会挂断流程。在循环中使用上述行解决了我的问题。用户界面没有挂起,用户可以在其他表单上工作。对我来说,这个出现的
progressbar现在是后台进程
(在某种程度上)


希望有帮助

这没有经过测试,但我记得我做过类似的事情,将信息提供给BGW。这将更新后台工作程序内容

首先用以下变量创建一个类(例如ProgExample),并将其作为全局对象

Dim ProgValue as Integer;
Dim ProgMax as Integer;
然后将类馈送给后台工作程序

BackgroundWorker1.RunWorkerAsync(_ProgExample)
阅读并把它放在里面:

Dim BGWProgExample as ProgExample = DirectCast(e.Argument, ProgExample), 
在后台工作人员中,执行以下操作:

BGWProgressBar.Maximum = BGWProgExample.ProgMax
while BGWProgExample.ProgValue <> BGWProgExample.ProgMax
BGWProgressBar.Value = BGWProgExample.ProgValue 
BGWProgressBar.max=BGWProgExample.ProgMax
而BGWProgExample.ProgValue BGWProgExample.ProgMax
BGWProgressBar.Value=BGWProgExample.ProgValue

因此,当您完成某项工作时,只需更新_ProgExample.ProgValue即可。不要试图在没有类的情况下通过将ProgValue作为参数传递来实现这一点。这意味着您发送了一份处于当前状态的ProgValue副本,如果您要更新ProgValue,它将不会更改。如果这没有任何作用,请尝试将Application.DoEvents和/或Application.DoAction与此一起使用

也许我不明白这个问题,但这不是很简单吗

For i = ProgressBar1.Minimum To ProgressBar1.Maximum
        ProgressBar1.Value = i
        ProgressBar1.Update()
        System.Threading.Thread.Sleep(25)
    Next
Progressbar的“更新”实现了这一点。您的代码“阻塞”(虽然我不明白为什么需要“应用程序不响应”),但Progressbar得到更新d


顺便说一句:对于Windows Vista/7(progressbar动画),您可以检查以下内容:

我理解您希望将progressbar作为背景线程,但我相当肯定您将无法完成此操作。因为要更新应用程序的可视组件,所以UI需要是主线程。禁用表单上的所有控件(包括菜单项)非常容易

让我建议这个过程:

  • 使用上面提到的进度条显示您的表单

  • 如果显示任何其他窗体,请禁用直接位于窗体上的所有子控件。根据控件的不同,您可能必须遍历其子控件才能禁用它们

  • 在执行数据库更新的代码中,将progressbar的值更新为所需的值。更新值后,调用progressbar的刷新方法。这将强制progressbar正确绘制

  • 更新完成后,隐藏progressbar,重新启用禁用的所有窗体上的所有控件

  • 这将为您提供一个在后台线程中运行的progressbar的外观,同时仍然根据需要为您的应用程序提供主线程的阻塞。

    首先阅读以下内容:

    因此,在阅读上述答案后,您将永远不会再次使用DoEvents,并且如果没有DoEvents(和/或使ProgressBar无效以便其绘制事件将触发),“ProgressBar将不会动画,因为升级过程非常密集”


    因此,Cthulhu的评论——“您可以使用progressbar创建一个对话框,使该对话框成为模态,并在backgroundworker上执行您的db内容。”是最好的方法之一

    我已经翻译了一个我使用的C#实现,你应该可以直接把它放进去

    这是ProgressBar表单:

    Public Partial Class ThinkingProgressBar
        Inherits Form
        Private startTime As System.DateTime = DateTime.Now
        Public Sub New()
            InitializeComponent()
        End Sub
    
        Private Sub lblClose_LinkClicked(sender As Object, e As LinkLabelLinkClickedEventArgs)
            Me.Tag = "Cancelled"
            Me.Hide()
        End Sub
    
        Public Sub SetThinkingBar(ByVal switchedOn As Boolean)
            If switchedOn Then
                lblTime.Text = "0:00:00"
                startTime = DateTime.Now
                Timer1.Enabled = True
                Timer1.Start()
            Else
                Timer1.Enabled = False
                Timer1.Stop()
            End If
        End Sub
    
        Private Sub timer1_Tick(sender As Object, e As EventArgs)
            Dim diff As New TimeSpan()
            diff = DateTime.Now.Subtract(startTime)
            lblTime.Text = diff.Hours & ":" & diff.Minutes.ToString("00") & ":" & diff.Seconds.ToString("00")
            lblTime.Invalidate()
        End Sub
    End Class
    
    将BackgroundWorker控件拖放到窗体上,以下是后台工作程序事件:

    Private Sub backgroundWorker1_DoWork(sender As Object, e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        e.Result = e.Argument
        'DirectCast(e.Result, ThinkingProgressBar).SetThinkingBar(True) 
        'DO LONG OPERATION HERE
        
    End Sub
    
    Private Sub backgroundWorker1_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
        Dim dlg As ThinkingProgressBar = TryCast(e.Result, ThinkingProgressBar)
        If IsNothing(dlg) = False Then
            dlg.SetThinkingBar(False)
            dlg.Close()
        End If
    End Sub
    
    以下是应用程序启动和升级时的调用代码:

    Dim dlg As New ThinkingProgressBar()
    dlg.SetThinkingBar(True)
    BackgroundWorker1.RunWorkerAsync(dlg)
    dlg.ShowDialog()
    If IsNothing(dlg.Tag) = False AndAlso dlg.Tag.ToString() = "Cancelled" Then
        Return
    End If
    
    有几件事,您可以阻止用户取消(即
    lblClose\u LinkClicked
    ),并设置保护性/防御性编程,以处理用户在升级过程中终止进程或关闭电脑的情况

    ProgressBar实际上是一个动画gif,这将适合您的使用,因为很难预测更新数据库所需的时间:


    您可以使用progressbar创建一个对话框,使该对话框成为模态,并在backgroundworker上执行db内容。这正是我不想做的。我想反过来做。升级代码非常庞大,如果可以避免的话,我不想把它移到后台工作程序中(不是为了懒惰,而是为了可读性)。这样做是完全可能的。移动更新代码应该