从BackgroundWorker调用的计时器 - 奇怪的问题 [英] Timer called from BackgroundWorker-strange problems

查看:83
本文介绍了从BackgroundWorker调用的计时器 - 奇怪的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述





我正在制作一个完成此流程的程序:



1 )执行任务1

2)将进度条更新为33%

3)执行任务2

4)将进度条更新为67%

5)执行任务3

6)将进度条更新为100%

7)Msgbox(完成)



我省略了这些任务,因为它们与这个问题无关。



问题是进度条只有在msgbox是在Tick1()事件中显示,将焦点从表单上移开。



我有3个BackgroundWorkers:Part1,Part2和Part3。

我还有3个计时器:Increment1Timer,Increment2Timer和Increment3Timer。



这是我的代码:

Hi,

I'm making a program that goes through this flow:

1) Do Task 1
2) Update progressbar to 33%
3) Do Task 2
4) Update progressbar to 67%
5) Do Task 3
6) Update progressbar to 100%
7) Msgbox("Done")

I've omitted the tasks because they're unrelated to this question.

The problem is that the progressbar only updates if a msgbox is shown in the Tick1() event, taking focus away from the form.

I have 3 BackgroundWorkers: Part1, Part2 and Part3.
I also have 3 timers: Increment1Timer, Increment2Timer and Increment3Timer.

This is my code:

Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
            Part1.RunWorkerAsync()
    End Sub
   
    Private Sub Part1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles Part1.DoWork
        PictureBox1.Image = My.Resources.shield
        Label1.Text = "Performing task 1..."
        Try
       (Do Task 1)
            Threading.Thread.Sleep(2000)
            Increment1Timer.Start()
             Catch ex As Exception
            Threading.Thread.Sleep(2000)
            PictureBox1.Image = My.Resources.cross
            Label1.Text = "Error-UAC required"
            Threading.Thread.Sleep(2000)
            Dim proc As New ProcessStartInfo
            proc.UseShellExecute = True
            proc.WorkingDirectory = Environment.CurrentDirectory
            proc.FileName = Application.ExecutablePath
            proc.Verb = "runas"
            Try
                Process.Start(proc)
            Catch ex2 As Exception
            End Try
            Application.Exit()
        End Try
    End Sub
    Private Delegate Sub DoUIWorkHandler()
    Private Sub Increment1Timer_Tick(sender As System.Object, e As System.EventArgs) Handles Increment1Timer.Tick
        If (NeroBar1.InvokeRequired) Then
            NeroBar1.Invoke(New DoUIWorkHandler(AddressOf Tick1))
        Else
            Tick1()
        End If
    End Sub
    Private Sub Tick1()
        If NeroBar1.Value = 33 Then
            Increment1Timer.Stop()
            Part2.RunWorkerAsync()
        Else
            NeroBar1.Value += 1
        End If
    End Sub
    Private Sub Part2_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles Part2.DoWork
        PictureBox1.Image = My.Resources.task
        Label1.Text = "Performing task 2..."
              (Do Task 2)
              Threading.Thread.Sleep(2000)
        Part2.ReportProgress(67)
        Increment2Timer.Start()
    End Sub
    Private Sub Increment2Timer_Tick(sender As System.Object, e As System.EventArgs) Handles Increment2Timer.Tick
        If (NeroBar1.InvokeRequired) Then
            NeroBar1.Invoke(New DoUIWorkHandler(AddressOf Tick2))
        Else
            Tick2()
        End If
    End Sub
    Private Sub Tick2()
        If NeroBar1.Value = 67 Then
            Increment2Timer.Stop()
            Part3.RunWorkerAsync()
        Else
            NeroBar1.Value += 1
        End If
    End Sub
    Private Sub Part3_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles Part3.DoWork
        PictureBox1.Image = My.Resources.task
        Label1.Text = "Performing task 3..."
        Part3.ReportProgress(100)
        Increment3Timer.Start()
    End Sub
    Private Sub Increment3Timer_Tick(sender As System.Object, e As System.EventArgs) Handles Increment3Timer.Tick
        If NeroBar1.Value = 100 Then
            If (NeroBar1.InvokeRequired) Then
                NeroBar1.Invoke(New DoUIWorkHandler(AddressOf Tick3))
            Else
                Tick3()
            End If
                   MsgBox("Done")
        Else
            NeroBar1.Value += 1
        End If
    End Sub
    Private Sub Tick3()
        If NeroBar1.Value = 100 Then
            Increment1Timer.Stop()
        Else
            NeroBar1.Value += 1
        End If
    End Sub





请帮忙!



Please help!

推荐答案

不确定是否OP仍然需要一个解决方案来判断他得到了什么回复 - 没有任何价值 - 以及这个问题的发布日期。



发送时遇到类似情况带附件的电子邮件。我使用单个Timer控件来管理我的Backgroundworker的触发顺序,其中包含在下一个Backgroundworker触发之前必须满足的2个条件,这些是(1)Label控件以确认先前的操作已成功完成(和2)之前的Backgroundworker已经结束 - 你不希望两个后台工作者同时运行,特别是当一个人依赖于另一个人完成的工作时。



发送带附件的电子邮件(来自数据库的图像)时,我的工作流程如下:

(1)从DB中检索图像(二进制格式)到内存流中。将内存流保存到本地磁盘上的文件。

(2)准备并发送附带附件的电子邮件。

(3)从文件系统中删除图像。



在此过程中,我更新了标签和进度条。



这是使用3个背景工作者的逻辑定时器控制:



Not sure if the OP is still in need of a solution judging from what replies he got - nothing of value - and the date this question was posted.

I have a similar situation while sending an email with attachments. I use a single Timer control to manage the "firing" order of my Backgroundworker with the 2 conditions that must be met before the next Backgroundworker will fire, these are (1) a Label control to confirm that the previous action has successfully completed and (2) that the previous Backgroundworker has ended - you don't want two backgroundworkers to run at the same time, especially when the one is dependent on the work done by the other.

When sending an email with attachments (images from a DB) this is how my workflow for:
(1) Retrieve images (binary format) from DB into memory stream. Save the memorystream to a file on the local disk.
(2) Prepare and send email with attachments.
(3) Remove images from file system.

During the process I update a Label and a Progressbar.

This is the logic behind using 3 Backgroundworkers with a single Timer control:

'***********************************************************************************
 '* IMPORTANT !!!!!                                                                 *
 '*-----------------                                                                *
 '* We will be using 3 BackgroundWorkers to accomplish sending an Email message.    *
 '* 1. Export Images  (bkwExportImg)                                                *
 '* 2. Send Messsage  (bkwSendMsg)                                                  *
 '* 3. Delete Images  (bkwDeleteImg)                                                *
 '* !!! BackgroundWorkers are fired up in the above order by means of a Timer!!!    *
 '* Threads are used to update the Main form UI                                     *
 '***********************************************************************************
 'TIMER - Timer is used to fire the Send Message Backgroundworkers sequentially
 Private Sub tmrBackgroundworker_Tick(sender As System.Object, e As System.EventArgs) Handles tmrBackgroundworker.Tick
     If bgwExportImage.IsBusy = False AndAlso Me.tsSendMailStatus.Text = "Preparing Email message" Then
         'Start the Export process
         bgwExportImage.RunWorkerAsync()
     ElseIf bgwSendMessage.IsBusy = False AndAlso Me.tsSendMailStatus.Text = "Export completed" Then
         'Send the message
         bgwSendMessage.RunWorkerAsync()
     ElseIf bgwDeleteImages.IsBusy = False AndAlso Me.tsSendMailStatus.Text = "Message sent" Then
         'Delete Image files
         bgwDeleteImages.RunWorkerAsync()
     End If
 End Sub





我希望这可以帮到你一点点。它对我来说非常好用,并且已经有一段时间完美地工作了一段时间我没有一个单一的例子,它在我身上失败了。



要保留的东西在尝试解雇第一个背景工作者之前,首先要测试任何背景工作者是否正在运行。



I hope this helps you out a little. It works really well for me and has been working perfectly for some time now and I haven't has a single instance where it failed on me.

Something to keep in mind is to first test if any backgroundworkers are running before you attempt to fire your first backgroundworker.


这篇关于从BackgroundWorker调用的计时器 - 奇怪的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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