问题在于停止后台工作进程中的操作。

huangapple go评论59阅读模式
英文:

Problem in stopping the operation in background worker

问题

我想每隔半秒运行一些带有不同文本的日志,并在完成后停止。但我希望在单击停止按钮时停止,并且不显示其余的日志。

目前,当我单击停止按钮时,它在显示其余的日志后停止。

我放置了我的代码如下。

Public WithEvents worker As New BackgroundWorker

Public Sub New()
    InitializeComponent()
    worker.WorkerSupportsCancellation = True
    worker.WorkerReportsProgress = True
End Sub

Private Sub start_Click(sender As Object, e As RoutedEventArgs) Handles start.Click
    If Not worker.IsBusy Then
        'check = False
        worker.RunWorkerAsync()
        start.Content = "停止"
    Else
        worker.CancelAsync()
        start.Content = "读取信息"
    End If
End Sub

Public Sub XmlWrite(sender As Object, e As DoWorkEventArgs) Handles worker.DoWork
    While (Not worker.CancellationPending)
        If Not worker.CancellationPending Then
            Working()
            flash_log("操作已完成 ", MsgType.warning, True)
        Else
            Exit While
            Exit Sub
            log("操作已取消")
            worker.CancelAsync()
            Button.Content = "读取信息"
        End If
    End While
End Sub
   
End Sub

Private Sub Working()
    log("你好世界  ")   '///// 这是日志函数
    log.Delay(0.5)
    log("我是开发者")
    log.Delay(0.5)
    log("我的名字是沙哈布 ")
    log.Delay(0.5)
    log("我的年龄是31岁")
    log.Delay(0.5)
    log("我喜欢vb.net")
    log.Delay(0.5)
    If worker.IsBusy Then
        worker.CancelAsync()
    End If
End Sub
英文:

I want to run a number of logs with different text after every half second and stop after finishing. But I want it to stop when I click on the stop button and not show the rest of the logs.

Currently, when I click on the stop button, it stops after displaying the rest of the logs.

I put my code below.

Public WithEvents worker As New BackgroundWorker

Public Sub New()
    InitializeComponent()
    worker.WorkerSupportsCancellation = True
    worker.WorkerReportsProgress = True
End Sub

Private Sub start_Click(sender As Object, e As RoutedEventArgs) Handles start.Click
    If Not worker.IsBusy Then
        'check = False
        worker.RunWorkerAsync()
        start.Content = "STOP"
    Else
        worker.CancelAsync()
        start.Content = "Read Info"
    End If
End Sub

Public Sub XmlWrite(sender As Object, e As DoWorkEventArgs) Handles worker.DoWork
    While (Not worker.CancellationPending)
        If Not worker.CancellationPending Then
            Working()
            flash_log("Operation Completed ", MsgType.warning, True)
        Else
            Exit While
            Exit Sub
            log("Operation Canceled")
            worker.CancelAsync()
            Button.Content = "Read Info"
        End If
    End While
End Sub
   
End Sub

Private Sub Working()
    log("hello world  ")   '///// this is log Function
    log.Delay(0.5)
    log("I am Developer")
    log.Delay(0.5)
    log("My name Is shahab ")
    log.Delay(0.5)
    log("my Age Is 31")
    log.Delay(0.5)
    log("I love vb.net")
    log.Delay(0.5)
    If worker.IsBusy Then
        worker.CancelAsync()
    End If
End Sub

答案1

得分: 2

以下是翻译好的部分:

你的代码是在尝试编写代码而不知道代码首先要做什么时最终得到的结果。你应该始终先制定逻辑,然后编写专门用于实现该逻辑的代码。看看你的代码实际上做了什么。它首先检查CancellationPending,然后开始写入日志,直到写完所有日志后才再次检查CancellationPending。如果你在写入期间不检查CancellationPending,你为什么会期望它退出?

逻辑,最基本的形式是写第一条日志,然后检查是否挂起取消,然后写第二条日志,然后检查是否挂起取消,依此类推。在这个非常假设的情况下,你可能应该做的是将所有消息放入列表中,然后在该列表上使用循环。在循环内部,你可以写下一条日志并检查是否挂起取消。

请注意RunWorkerCompleted事件的正确使用。

英文:

Your code is the sort of thing that you end up with when you try to write code without knowing what the code has to do first. You should ALWAYS work out the logic first, then write code to implement that specifically. Look at what your code actually does. It checks CancellationPending first, then it starts writing to the logs and it doesn't check CancellationPending again until it has written all the logs. If you don't check CancellationPending between writing, why would you expect it to exit?

The logic, in it's most form, is write the first log and then check whether cancellation is pending, then write the second log and then check whether cancellation is pending, etc, etc. What you probably ought to do in this very contrived case is to put all the messages in a list and then use a loop over that list. Inside the loop, you can write the next log and check whether a cancellation is pending.

Public Sub XmlWrite(sender As Object, e As DoWorkEventArgs) Handles worker.DoWork
    Dim logEntries = {
        "hello world  ",
        "I am Developer",
        "My name Is shahab ",
        "my Age Is 31",
        "I love vb.net"}

    For Each logEntry In logEntries
        If worker.CancellationPending Then
            e.Cancel = True

            Exit For
        End If

        log(logEntry)
        log.Delay(0.5)
    Next
End Sub

Private Sub worker_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles worker.RunWorkerCompleted
    If e.Cancelled Then
        Log("Operation Canceled")
    Else
        flash_log("Operation Completed ", MsgType.warning, True)
    End If

    start.Content = "Read Info"
End Sub

Note the proper use of the RunWorkerCompleted event as well.

huangapple
  • 本文由 发表于 2023年6月26日 14:20:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/76553987.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定