I'm having a problem with a static class constructor being called twice. I
have the static class MasterTaskList which uses a BackgroundWorker to execute
multiple methods on a separate thread. The static constructor calls a reset
function which creates a new instance of BackgroundWorker and attaches the
appropriate event handlers. There is also a static method ReportProgress for
the called methods to do just that.
What is happening is that the static class is initialized the first time,
functions are added to the list to be executed, the BackgroundWorker is
started, and one of the methods called by the BackgroundWorker's thread calls
MasterTaskList.ReportProgress(). This access of the MasterTaskList class
causes the static constructor to be called again. See below for the callstack
from the second call to the static constructor.
What I can't fathom is how it is possible for a static method from a static
class to appear in the callstack for a static constructor.
Here's a couple of other twists:
1) This only happens when the calls are made by a Windows service. Identical
calls in a regular Windows app work fine.
2) The call to ReportProgress() that does this isn't the first time it's
called within the scope of
Master.Common.Task.MasterTaskList.InternalCalculat ion(). It is the first time
it's called within Master.Bar.Calculation.Foo.FooCalculation.LoadData ()
3) The static constructor sets the BackgroundWorker instance of
MasterTaskList to a new BackgroundWorker. The original BackgroundWorker
continues to run, but doesn't fire it's RunWorkerCompleted event when
finished.
4) I can attach to this process running as a Windows service and step
through to right before it calls the static constuctor again. Using
Quickwatch, I can see that the MasterTaskList it's about to call is already
initialized. After it's called, the events in the class all get disconnected
and the only thing left running is the stranded BackgroundWorker thread.
This one has left me scratching my head.
Thanks for any help in advance,
Matt
Here is the call stack from the static constructor:
at Master.Common.Task.MasterTaskList..cctor()
at Master.Common.Task.MasterTaskList.ReportProgress()
at Master.Bar.Calculation.Foo.FooCalculation.LoadData (Object sender,
EventArgs e)
at Master.Bar.BarMaster.LoadData(Object sender, EventArgs e)
at Master.Common.Task.MasterTaskList.ExecuteTask(Mast erTask currentTask)
at Master.Common.Task.MasterTaskList.InternalCalculat ion(Object sender,
DoWorkEventArgs e)
at System.ComponentModel.BackgroundWorker.OnDoWork(Do WorkEventArgs e)
at System.ComponentModel.BackgroundWorker.WorkerThrea dStart(Object
argument)
at
System.Runtime.Remoting.Messaging.StackBuilderSink ._PrivateProcessMessage(IntPtr
md, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext,
Object[]& outArgs)
at
System.Runtime.Remoting.Messaging.StackBuilderSink .PrivateProcessMessage(RuntimeMethodHandle
md, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext,
Object[]& outArgs)
at
System.Runtime.Remoting.Messaging.StackBuilderSink .AsyncProcessMessage(IMessage msg, IMessageSink replySink)
at
System.Runtime.Remoting.Proxies.AgileAsyncWorkerIt em.ThreadPoolCallBack(Object o)
at System.Threading._ThreadPoolWaitCallback.WaitCallb ack_Context(Object
state)
at System.Threading.ExecutionContext.Run(ExecutionCon text
executionContext, ContextCallback callback, Object state)
at System.Threading._ThreadPoolWaitCallback.PerformWa itCallback(Object
state)