英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论