Results 1 to 8 of 8

Thread: Deadlock in Background Worker

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Feb 2004
    Location
    India
    Posts
    506

    Question 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

  2. #2
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    106,307

    Re: Deadlock in Background Worker

    Do it like this:
    vb.net Code:
    1. Private actionList As New ConcurrentQueue(Of String)
    2.  
    3. Private Sub AddAction(action As String)
    4.     actionList.Enqueue(action)
    5. End Sub
    6.  
    7. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    8.     BackgroundWorker1.RunWorkerAsync()
    9. End Sub
    10.  
    11. Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    12.     Do Until actionList.IsEmpty
    13.         Dim action As String
    14.  
    15.         If actionList.TryDequeue(action) Then
    16.             'Use action here.
    17.         End If
    18.     Loop
    19. 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.

  3. #3

    Thread Starter
    Hyperactive Member
    Join Date
    Feb 2004
    Location
    India
    Posts
    506

    Post 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.

  4. #4
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    106,307

    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:
    1. Imports System.Collections.Concurrent
    2. Imports System.Runtime.CompilerServices
    3.  
    4. Public Module ConcurrentQueueExtensions
    5.  
    6.     <Extension>
    7.     Public Sub Clear(Of T)(source As ConcurrentQueue(Of T))
    8.         Do Until source.IsEmpty
    9.             source.TryDequeue(Nothing)
    10.         Loop
    11.     End Sub
    12.  
    13. End Module

  5. #5
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    35,800

    Re: Deadlock in Background Worker

    Quote Originally Posted by greatchap View Post
    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

  6. #6

    Thread Starter
    Hyperactive Member
    Join Date
    Feb 2004
    Location
    India
    Posts
    506

    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

  7. #7
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    106,307

    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.

  8. #8

    Thread Starter
    Hyperactive Member
    Join Date
    Feb 2004
    Location
    India
    Posts
    506

    Re: Deadlock in Background Worker

    Quote Originally Posted by jmcilhinney View Post
    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
  •  



Click Here to Expand Forum to Full Width