By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,897 Members | 1,490 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,897 IT Pros & Developers. It's quick & easy.

Asynch crash when e.Cancel set?

P: n/a
Does anyone knmow why an asynchronous worker method would crash if the
e.Cancel method is set to true, but not otherwise?

I'm working on a demo app with an asynchronous call, using the .NET 2.0
BackgroundWorker component. The app works fine if I let the worker method
proceed to completion. But if I cancel the worker method, it crashes.

Specifically, if I set the DoWorkEventArgs.Cancel property to true, the
worker thread crashes at the point where the worker method returns control
to the caller. If I set the Cancel flag to false, the operation is
cancelled, but the RunWorkerCompletedEventArgs.Cancelled property is wrong.

My worker method is called by the BackgroundWorker_DoWork event handler,
which passes in a WidgetList, a reference to the background worker (which
DoWork cast from its sender argument), and the DoWork event arguments. Here
is the worker method code:

private WidgetList PopulateList(WidgetList sourceList, BackgroundWorker
backgroundWorker, DoWorkEventArgs e)
{
// Create deep copy (by serialization)
WidgetList resultList = sourceList.DeepCopy();

// Populate result list
for (int i = 0; i < 100; i++)
{
// Add new widget to the list
WidgetItem widget = new WidgetItem(i);
resultList.Add(widget);

// Pause to simulate slow process
Thread.Sleep(100);

// Check cancellation
if (backgroundWorker.CancellationPending)
{
// Set DoWork event args
e.Cancel = false;

// Return unmodified list
return sourceList;
}

// Report progress
backgroundWorker.ReportProgress(i);
}

// Set return value
return resultList;
}

And here is the exception I'm getting when the app stops:

System.Reflection.TargetInvocationException was unhandled
Message="Exception has been thrown by the target of an invocation."
Source="mscorlib"
StackTrace:
at System.RuntimeMethodHandle._InvokeMethodFast(Objec t target,
Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes,
RuntimeTypeHandle typeOwner)
at System.RuntimeMethodHandle.InvokeMethodFast(Object target,
Object[] arguments, Signature sig, MethodAttributes methodAttributes,
RuntimeTypeHandle typeOwner)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj,
BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo
culture, Boolean skipVisibilityChecks)
at System.Delegate.DynamicInvokeImpl(Object[] args)
at
System.Windows.Forms.Control.InvokeMarshaledCallba ckDo(ThreadMethodEntry
tme)
at System.Windows.Forms.Control.InvokeMarshaledCallba ckHelper(Object
obj)
at System.Threading.ExecutionContext.runTryCode(Objec t userData)
at
System.Runtime.CompilerServices.RuntimeHelpers.Exe cuteCodeWithGuaranteedCleanup(TryCode
code, CleanupCode backoutCode, Object userData)
at System.Threading.ExecutionContext.RunInternal(Exec utionContext
executionContext, ContextCallback callback, Object state)
at System.Threading.ExecutionContext.Run(ExecutionCon text
executionContext, ContextCallback callback, Object state)
at
System.Windows.Forms.Control.InvokeMarshaledCallba ck(ThreadMethodEntry tme)
at System.Windows.Forms.Control.InvokeMarshaledCallba cks()
at System.Windows.Forms.Control.WndProc(Message& m)
at
System.Windows.Forms.Control.ControlNativeWindow.O nMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.W ndProc(Message&
m)
at System.Windows.Forms.NativeWindow.DebuggableCallba ck(IntPtr hWnd,
Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchM essageW(MSG&
msg)
at
System.Windows.Forms.Application.ComponentManager. System.Windows.Forms.UnsafeNativeMethods.IMsoCompo nentManager.FPushMessageLoop(Int32
dwComponentID, Int32 reason, Int32 pvLoopData)
at
System.Windows.Forms.Application.ThreadContext.Run MessageLoopInner(Int32
reason, ApplicationContext context)
at
System.Windows.Forms.Application.ThreadContext.Run MessageLoop(Int32 reason,
ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at BackgroundWorkerDemo.Program.Main() in C:\Documents and
Settings\David Veeneman\My Documents\Visual Studio
2005\Demos\BackgroundWorkerDemo\Program.cs:line 17
at System.AppDomain.nExecuteAssembly(Assembly assembly, String[]
args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence
assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.Run UsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context( Object state)
at System.Threading.ExecutionContext.Run(ExecutionCon text
executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()

Any ideas as to what's going on here? Thanks.

--
David Veeneman
Foresight Systems

Aug 2 '06 #1
Share this Question
Share on Google+
1 Reply


P: n/a
I found my answer. In the DoWorkEventArgs, e.Result can't be set if e.Cancel
is set to true. In my worker method, I was setting e.Cancel to true, then
setting e.Cancel to my unmodified source list, as an easy way of providing a
rollback in a cancellation.

The error doesn't show up until .NET creates the RunWorkerCompletedEventArgs
for the RunWorkerCompleted event. When it tries to set the e.Result
property, an InvalidOperationException will be thrown, with the error
message "Operation has been cancelled". If you then try to read e.Result in
the RunWorkerCompleted event handler, the app blows up. The moral of the
story is to check for cancellation before reading e.Result in a
RunWorkerCompleted event handler.

--
David Veeneman
Foresight Systems
Aug 2 '06 #2

This discussion thread is closed

Replies have been disabled for this discussion.