-
Jan 21st, 2021, 05:34 AM
#1
Thread Starter
Fanatic Member
Deadlock in Background Worker
Hello,
I have a program that calls a background worker. In the background worker is a list of tasks for it. More items can be added to the list by main code. However that no. won't exceed 5.
However the background worker is getting stuck.
Code:
Private Sub BWorker2_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BWorker2.DoWork
'JAN 2021
If AlertList.Count = 0 Then Exit Sub
Dim segment As String = AlertList(0)
File.AppendAllText("NewAlertLog.txt", "Starting alert for " & segment & " at " & Format(Now, "dd-MM-yyyy HH:mm:ss") & vbCrLf)
If segment.ToLower = "stockfut" Then
AlertStockFut.StartAlert()
ElseIf segment.ToLower = "index" Then
AlertIndex.StartAlert()
ElseIf segment.ToLower = "equity" Then
AlertEq.StartAlert()
ElseIf segment.ToLower = "curr" Then
AlertCurr.StartAlert()
ElseIf segment.ToLower = "mt" Then
AlertMetals.StartAlert()
End If
File.AppendAllText("NewAlertLog.txt", "Alert sent for " & segment & " at " & Format(Now, "dd-MM-yyyy HH:mm:ss") & vbCrLf)
AlertList.RemoveAt(0)
End Sub
Private Sub BWorker2_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BWorker2.RunWorkerCompleted
If AlertList.Count > 0 Then
File.AppendAllText("NewAlertLog.txt", "Calling BWorker2 again. Cnt: " & AlertList.Count & " at " & Format(Now, "dd-MM-yyyy HH:mm:ss") & vbCrLf)
BWorker2.RunWorkerAsync()
End If
If AlertList.Count = 0 Then
File.AppendAllText("NewAlertLog.txt", "All alerts completed at " & Format(Now, "dd-MM-yyyy HH:mm:ss") & vbCrLf)
End If
End Sub
When above code runs sometimes AlertList.count is 5 and background worker is busy all the time.
I don't know what to do ?. If anyone can help it will be great.
Regards,
GR
-
Jan 21st, 2021, 06:30 AM
#2
Re: Deadlock in Background Worker
Do it like this:
vb.net Code:
Private actionList As New ConcurrentQueue(Of String)
Private Sub AddAction(action As String)
actionList.Enqueue(action)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Do Until actionList.IsEmpty
Dim action As String
If actionList.TryDequeue(action) Then
'Use action here.
End If
Loop
End Sub
The ConcurrentQueue is specifically intended to be used across threads and a queue is specifically intended for items to be added at one end and removed at the other, unlike a list. There's no need to keep starting the background task over and over when you can just loop in the one task as long as there's work to do.
-
Jan 21st, 2021, 06:57 AM
#3
Thread Starter
Fanatic Member
Re: Deadlock in Background Worker
Thank you jmcilhinney.
I am actually calling this from another background worker so I am only check for the first element and not running a loop. Usually 1 item is added then some work is done then another item is added. So on ...
I will try what you mentioned and then lets see if it works. How can I clear actionlist with one command?
Last edited by greatchap; Jan 21st, 2021 at 07:02 AM.
-
Jan 21st, 2021, 07:18 AM
#4
Re: Deadlock in Background Worker
The ConcurrentQueue class has no Clear method but, if you want to clear it, you can just dequeue in a loop as I demonstrated. Here's an extension method that will allow you to call Clear like you would on a List:
vb.net Code:
Imports System.Collections.Concurrent
Imports System.Runtime.CompilerServices
Public Module ConcurrentQueueExtensions
<Extension>
Public Sub Clear(Of T)(source As ConcurrentQueue(Of T))
Do Until source.IsEmpty
source.TryDequeue(Nothing)
Loop
End Sub
End Module
-
Jan 21st, 2021, 10:32 AM
#5
Re: Deadlock in Background Worker
Originally Posted by greatchap
Thank you jmcilhinney.
I am actually calling this from another background worker so I am only check for the first element and not running a loop. Usually 1 item is added then some work is done then another item is added. So on ...
I will try what you mentioned and then lets see if it works. How can I clear actionlist with one command?
I think you might be making this more complicated than it should be, though I agree with the concurrent queue. After all, if I am understanding you right, you have one thread (the first BGW) starting a second thread (the BGW shown in the first post) that starts a third thread (the items being started in the BGW shown).
I see no value to the second of those. The first BGW can launch the third tasks directly. After all, it is already running in the background, and starting those tasks will take a tiny fraction of a millisecond, so having the first BGW start the tasks rather than leaving it to the second shouldn't make any difference even if the first BGW is doing something very time sensitive.
My usual boring signature: Nothing
-
Jan 22nd, 2021, 03:34 AM
#6
Thread Starter
Fanatic Member
Re: Deadlock in Background Worker
Hello Everyone,
Thank you for your inputs. Somehow this whole thing is not working.
I have a background worker that does some processing and fires alerts and then does processing and fire alerts. Earlier it worked in serial manner i.e. a) do processing b) fire alerts c) do processing d) fire alerts so on and then stop. The problem here is while alerts are being fired processing for next item would get delayed. So I wrote code that would call another background worker to fire alert. And in main alert list I would add names after processing of data is done so that in background worker completed it re-initiates till list count is not 0.
But its getting locked up somehow, I mean background worker 2 is busy most of the time if even alert count is 0. Dont know whats going wrong.
Regards,
GR
-
Jan 22nd, 2021, 03:48 AM
#7
Re: Deadlock in Background Worker
Add some logging to your code so you can see what's happening when and where. You can't just use the debugger when you have multiple threads because it's too hard to work out what's going on in what thread.
-
Jan 22nd, 2021, 07:57 AM
#8
Thread Starter
Fanatic Member
Re: Deadlock in Background Worker
Originally Posted by jmcilhinney
Add some logging to your code so you can see what's happening when and where. You can't just use the debugger when you have multiple threads because it's too hard to work out what's going on in what thread.
I did and I found out that in one of the case after a alert was fired in 2nd background worker, the control should have gone to worker completed event. However it did not happen. The action array was empty but the worker is busy was True. Strange...
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|