BackgroungWork taske ended for no appearent reason

S

Stewart Berman

Windows XP Pro SP3 with all patches
Visual Studio 2005 with all patches
..Net 2.0

I have an application which runs starts a BackgroundWorker task the is supposed to run until either
the user clicks on a Stop button in the foreground GUI which signals a cancel to the
BackgroundWorker task or the system shuts down.

After running for approximately two and a half days the BackroundWorker task exited without being
asked to. The trace log indicates implies that there was an unhandled exception as a number of
lines are missing between the last normal trace output and the BackgroundWorker task ending trace
lines. The trace wrapper was not involved as there is code immediately after the last regular trace
statement that appears to not have been executed or that threw an unhandled error:

TraceWriteLineIf(cvarTraceSwitch.TraceInfo, Format$(Now(), "yyyyMMdd HH:mm:ss.fff:
") & "Converting to bitmap: " & sFilePathName)
sFilePathNameSave =
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\Wallpaper1.bmp"
img = Image.FromFile(sFilePathName)
img.Save(sFilePathNameSave, System.Drawing.Imaging.ImageFormat.Bmp) <== This was
not done.

If the above code (in a class instantiated by the BackgroundWorker task) threw an unhandled error
there should have been a messagebox on the scrren -- there wasn't any. (The execution of the method
in the class is not in a Try block in the BackgroundWorker_DoWork method.)

I pressed the Stop button on the GUI and got the following trace log entries:
20090717 12:36:04.687: btnStop_Click Tracing Started
20090717 12:36:04.687: StopSlideShow Tracing Started
20090717 12:36:04.687: ShutDownBackgroundTask Tracing Started
20090717 12:36:04.750: Dispose Tracing Started
20090717 12:36:04.750: Dispose Tracing Ended
20090717 12:36:04.750: ShutDownBackgroundTask Tracing Ended
20090717 12:36:04.750: StopSlideShow Tracing Ended
20090717 12:36:04.750: btnStop_Click Tracing Ended

I pressed the Start button and the BackgroundWorker task appeared to start correctly and begin
processing and logging.

It appears there was some type of error thrown that, instead of popping up an error message dialog
box set the Cancel flag of the BackgroundWorker class. Any explaination of what happened would be
appreaciated.


Pertinent details follow:

The code controlling the BackgroundWorker task is:

If (cvarTraceSwitch.TraceInfo) Then
TraceWriteLine(Format$(Now(), "yyyyMMdd HH:mm:ss.fff: ") &
System.Reflection.MethodBase.GetCurrentMethod.Name & " Tracing Started")
TraceIndent()
End If

CBackgroundWorker = CType(sender, BackgroundWorker)
lMemoryInUseStarting = MemoryInUse()
dataSet = LoadData(CType(e.Argument, DataSet))
CWallpaper = New Wallpaper()
Thread.CurrentThread.Priority = ThreadPriority.BelowNormal
Do While (Not CBackgroundWorker.CancellationPending)
<snip>
If (CBackgroundWorker.CancellationPending) Then
e.Cancel = True
ElseIf (0 <> Interlocked.Exchange(cvarReload, 0)) Then
dataSet.Dispose()
dataSet = Nothing
dataSet = LoadData(CType(e.Argument, DataSet))
End If
Loop
CBackgroundWorker = Nothing
CWallpaper = Nothing
dataRow = Nothing
dataSet = Nothing

If (cvarTraceSwitch.TraceInfo) Then
TraceUnindent()
TraceWriteLine(Format$(Now(), "yyyyMMdd HH:mm:ss.fff: ") &
System.Reflection.MethodBase.GetCurrentMethod.Name & " Tracing Ended")
End If

The do loop does not contain an "Exit Do" statement nor an "Exit Sub" statement. There are two
points in the applicatoin code that call the BackgroundWorker classes AsynchCancel method. On is in
the Dispose method of the BackgroundWorker class and the other is in the Stop button handled by the
Foreground form. Both include trace statements. The trace log file does not include trace
statements from either one.

The trace log includes:
20090717 07:03:02.328: Converting to bitmap: C:\Common\SlideShow\IMG_2287.JPG
<expected trace lines missing>
20090717 07:03:02.718: CBackgroundWorker_RunWorkerCompleted Tracing Started
20090717 07:03:02.718: OnRunWorkerCompleted Tracing Started
20090717 07:03:02.718: OnRunWorkerCompleted Tracing Ended
20090717 07:03:02.718: CBackgroundWorker_RunWorkerCompleted Tracing Ended
which implies the BackgroundWorker task ended normally.

The GUI has a Start and Stop button for starting and ending the BackgroundWorker task. The code in
the Start button disables itself and enables the Stop button. The code in the Stop button disables
itself and enables the Start button. When I checked the GUI the Start button was disabled and the
Stop button was enabled indicating that the Stop button's code had not been executed. The trace log
did not contain any messages from the Stop button code confirming that it had not been executed.

At 7:00 AM a daily incremental backup runs via Veritas BackupExec. The application had thrown an
unhandled exception at around that time last week because the trace log was in use so I put the
following wrapper around all Trace method calls:

Module TraceNoBlock

Private mconMILLISECONDSTIMEOUT As Integer = 100
Private mconMAXIMUMTRIES As Integer = 100

Private Sub SleepAndBeep(ByVal millisecondsTimeout As Integer)
Beep()
Thread.Sleep(millisecondsTimeout)
Beep()
End Sub

Public Sub TraceWriteLine(ByVal message As String)
TraceWriteLine(message, mconMILLISECONDSTIMEOUT)
End Sub
Public Sub TraceWriteLine(ByVal message As String, ByVal millisecondsTimeout As Integer)
Dim nTries As Integer = 1
Do While (nTries <= mconMAXIMUMTRIES)
Try
Trace.WriteLine(message)
Exit Do
Catch ex As Exception
SleepAndBeep(millisecondsTimeout)
nTries = nTries + 1
End Try
Loop
End Sub
<snip>

The above could cause a trace message to be lost but only if the trace log was locked for ten
seconds (100 tries x 100 millisecnds).
:
 
A

Andrew Morton

Windows XP Pro SP3 with all patches
Visual Studio 2005 with all patches
.Net 2.0

I have an application which runs starts a BackgroundWorker task the is
supposed to run until either
the user clicks on a Stop button in the foreground GUI which signals a
cancel to the
BackgroundWorker task or the system shuts down.

After running for approximately two and a half days the BackroundWorker
task exited without being
asked to.

Two-and-a-half /days/ ?

Does the task really take that much computation? Or are you really after a
service?

"If you want to write application that constantly monitors some files,
creates a log file, or anything else which runs constantly in the background
...."
http://www.developerfusion.com/article/3441/creating-a-windows-service-in-vbnet/

Andrew
 
S

Stewart Berman

This is a ClickOnce application. It installs in ...\local settings\apps\2.0\.... I don't think you
should use ClickOnce to distribute a service as it appears to be intended to be for per user
applications not per machine like a service.

It doesn't take very much computation at all as it sleeps most of the time.

It is a relatively simple application that I wrote to get familiar with .Net. It has a foreground
GUI that minimizes to an icon in the Tray. It has a backgroundworker task that wakes up after a
number of minutes and does some windows API calls and then goes back to sleep.

The amount of tracing done when the trace flags are set to information is enormous. Every
function/subroutine entry/exit is tracked as are all Try/Catch/Finally structures including some
that are auto generated by Visual Studio so I could understand the program flow.

The unusual ending of the BackgroundWorker task is exactly the type of thing I want to understand.
Something ended the thread in the middle of it running -- not sleeping -- without throwing an error.
This is the type of thing that drives you crazy in a production application. Much better to hit it
while trying to understand the environment then when dependent on it.

BTW, I have a similar application written in VB 6 that runs for weeks at a time. It started when I
logged in and ended when I logged out. You should be able to keep any application open as long as
you want to unless it has a resource or memory leak in which case you shouldn't be using it in the
first place. Services are for things that need to run when nobody is logged in or that need to act
as a gateway for all users of the machine or to perform tasks for all users of a machine. Check
your tray and Task Manager -- anything sitting in the tray and that is running in your security
context is a long running user application like my application.
 
A

Armin Zingler

Stewart said:
The unusual ending of the BackgroundWorker task is exactly the type
of thing I want to understand. Something ended the thread in the
middle of it running -- not sleeping -- without throwing an error.
This is the type of thing that drives you crazy in a production
application. Much better to hit it while trying to understand the
environment then when dependent on it.


Maybe I just didn't see it but did you put a Try-Catch around the whole code
in the thread's main procedure?

But wait, I forgot you're using the BackgroundWorker. I don't know what's
going on under the hood then but if it's not a big issue to use a Thread
instead, then you can write the Thread's main procedure on your own. All
information should then be in the exception object (maybe including it's
InnerExcpetion(s)).


Armin
 
S

Stewart Berman

No, the whole code in the thread's main procedure does not have a try/catch around it. In fact the
section of the code that the BackgroundWorker thread was in when it decided to exit did not have a
try/catch around it. So if it was an error that caused it to exit I would have expected an
unhandled exception to be thrown and that does not seem to have happened. The BackgroundWorker
DoWork method simply exited without any apparent reason.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top