Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 338
  • Last Modified:

Weird issue with BackgroundWorker

I am using a background worker in a winforms app which I have done several times.  However this time I am getting some weird results.  For one, when I run the function that uses the bgw, the UI for some reason goes unresponsive...something I have never seen in past usage.

Also, when I am trying to debug, I set a breakpoint on the DoWork event.  This gets hit normally, but my mouse cursor goes to a busy hourglass and just sits for about 4-5 seconds, then when I try to step to the next line, it is like I hit F5(run) and no more break points get hit...I also get no data returned and the app just acts like it is doing something, but it never returns.  The completed event never gets hit and the progress changed event doesn't get hit.

any thought...?  I have looked at old code where I have used this before and I am doing the exact same thing I always have...I have never seen this...
0
rgn2121
Asked:
rgn2121
  • 13
  • 6
  • 3
3 Solutions
 
nepaluzCommented:
show us some code you are using.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Pretty impossible to say without seeing some code...especially the DoWork() handler.

Are you using any third-party components/libraries in the application?
0
 
rgn2121Author Commented:
I do use the MS Log Parser COM control....that is the only thing I use that is not standard within the IDE.


Private Sub mLogWorker_DoWork(ByVal sender As Object, _
                                  ByVal e As System.ComponentModel.DoWorkEventArgs) Handles mLogWorker.DoWork

        Dim query As String = TryCast(e.Argument, String)

        If Not String.IsNullOrEmpty(query) Then

            mEventLogInstance.direction = "BW"

            e.Result = CreateDataTableFromEventLogs(EventLogger.Execute(query, EventLogInstance))
        Else
            Throw New ArgumentNullException("e.Argument", "The query to process was missing.")
            e.Cancel = True
            Return
        End If

    End Sub ' mLogWorker_DoWork

Open in new window

0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
rgn2121Author Commented:
Let me add a little background about what I am doing.  I have created a class to handle calls to server application logs.  The UI is used to allow the user to filter and sort and then I assemble the query and pass it in and run it.  If I just query the log, the codes runs and returns in about 1 sec.  If I do some filtering or sorting this might take a little longer, which is why I put the backgroundworker in.

This still works, but the UI freezes for some reason.  I set breakpoints on every line in the code above and once I hit the DOWork, it freezes for a few seconds and then I step in and nothing else gets hit and I get nothing returned...like the code goes someplace and is running but never comes back...
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Some ActiveX/COM controls silently marshal back to the main UI thread without you knowing.  Is line #10 hitting that Log Parser control?
0
 
rgn2121Author Commented:
yes, but when I debug and put breakpoints throughout that code, I never even get to line 4.  The code breaks on the DoWork and I get the hourglass.  I wait till it goes away and I try to step to line 4 and nothing else gets hit..it is just like what I would expect if I had no other break points set and I had hit F5...only I get no data.

It's like it works fine (other than the UI hanging) if I let it run....if I try to debug through no results.
0
 
rgn2121Author Commented:
And I don't see anything weird when the class itself gets created and those Log Parser objects get declared and instantiated.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Show us more code then...how are starting the BackgroundWorker()?
0
 
nepaluzCommented:
is the e-argument actually a string? then try directcasting it
0
 
rgn2121Author Commented:
After I create the 'EventLogControl" object this is the routine that gets called and starts everything up...

Private mEventLogger As New LogQueryClass
    Private mEventLogInstance As New COMEventLogInputContextClass
    Private WithEvents mLogWorker As BackgroundWorker
    Private mDisposedValue As Boolean = False        ' To detect redundant calls
    Private Const EVENT_LOG_QUERY As String = "SELECT {0} TO_UPPERCASE( EXTRACT_TOKEN(EventTypeName, 0, ' ') ) " & _
                                                "as EventType, TimeGenerated as EventTS, " & _
                                                "SourceName as EventSource, " & _
                                                "EventID, " & _
                                                "Message as EventMessage " & _
                                            "FROM \\{1}\{2} "
    

Public Sub QueryEventLogAsync(ByVal logEntryCount As String, _
                                    ByVal whereClause As String, _
                                    ByVal orderClause As String, _
                                    ByVal serverName As String, _
                                    ByVal logType As EventLogType)

        Dim query As String = EVENT_LOG_QUERY

        'Get where clause
        If Not String.IsNullOrEmpty(whereClause) Then
            query += whereClause
        End If
        'Get order clause
        If Not String.IsNullOrEmpty(orderClause) Then
            query += orderClause
        End If

        Dim qryString As String = String.Format(query, _
                                                logEntryCount, _
                                                serverName, _
                                                logType.ToString)
        If mLogWorker Is Nothing Then
            mLogWorker = New BackgroundWorker
            mLogWorker.WorkerReportsProgress = True
            mLogWorker.WorkerSupportsCancellation = True
        ElseIf mLogWorker.IsBusy Then
            'wait
            MsgBox("A query is currently being processed, please wait.", _
                    MsgBoxStyle.Information, "Busy")
            Exit Sub
        End If

        mLogWorker.RunWorkerAsync(qryString)

    End Sub 'QueryEventLogAsync

Open in new window

0
 
rgn2121Author Commented:
is the e-argument actually a string? then try directcasting it
Yes it is, I did and I got the same result...
0
 
nepaluzCommented:
I'd declare Private WithEvents mLogWorker As BackgroundWorker as Public in the UI class /  form.
0
 
rgn2121Author Commented:
so you mean where I do...
Private WithEvents mTempLogParser As EventLogControl

in the UI/Form, you would make that public?  
0
 
rgn2121Author Commented:
I have never had to do that before, but I made the change and it didn't work.  One other thing to point out, I have another app that uses the backgroundworker in the same way and it works exactly as I expect...no issues.  Although, I coded that app against 2.0, this one with the issues is using 3.5.  Maybe I should try running this as a 2.0 app?
0
 
rgn2121Author Commented:
Well, I went ahead and changed to a 2.0 app and that didn't work either.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
I don't see any red flags in the code...leading me to believe it is just the COM component acting funny because it's being used from a secondary thread.

Try running it directly from the main UI thread to see if it at least completes (yes, it will still lock up).
0
 
rgn2121Author Commented:
Yes it completes fine from the main UI thread.  This is how I originally had it, but that was before I added in the ability to filter and order the result set.  I guess I will just have to deal with the UI locking up...?
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
"...but that was before I added in the ability to filter and order the result set."

Make sure that it also completes fine from the main UI with the filter and ordering code as well.

If that is the case, then I would say the COM control is incompatible with the BackgroundWorker control.
0
 
rgn2121Author Commented:
So far the one running on the UI thread with filtering isn't working...not sure why.  Giving an error about my query format, but I am running the exact same query...just different threads...

SELECT TOP 50 TO_UPPERCASE( EXTRACT_TOKEN(EventTypeName, 0, ' ') ) as EventType, TimeGenerated as EventTS, SourceName as EventSource, EventID, Message as EventMessage FROM \\Server\Application WHERE EXTRACT_TOKEN(EventTypeName, 0, ' ') <> 'Warning' Order By TimeGenerated

SELECT TOP 50 TO_UPPERCASE( EXTRACT_TOKEN(EventTypeName, 0, ' ') ) as EventType, TimeGenerated as EventTS, SourceName as EventSource, EventID, Message as EventMessage FROM \\Server\Application WHERE EXTRACT_TOKEN(EventTypeName, 0, ' ') <> 'Warning' Order By TimeGenerated

I pulled these out into UltraEdit and they are the same...unless I missed something.
0
 
rgn2121Author Commented:
Scratch that last comment...I had passed the wrong variable when I was cutting out the BGW.  Everything runs fine and returns as it should.  The query takes about 14 seconds in both systems and both lock the UI...but the one with out the BGW can be debugged as expected.  

Maybe I should try running it using system.threading.thread?  Or is that a waste of my time?
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Hmmm...I think the BackgroundWorker utilizes the Thread Pool, which is MTA.

With a manual thread, we can set it explicitly to STA:

    Dim T As New Thread(AddressOf Foo)
    T.ApartmentState = ApartmentState.STA
    T.Start()

That might make the COM control happier.

Of course, now you have to do the marshalling manually with delegates and BeginInvoke() to update any controls back on the main UI thread.
0
 
rgn2121Author Commented:
For the project I am doing it isn't all that important to worry with having it on another thread.  I was more curious about the weird behavior.  If I do decide to come back to this just to test it out, I will comment on what I find...Thanks!
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

  • 13
  • 6
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now