When my threads complete, I keep getting exceptions thrown.
I can catch them, but I'd rather my code catch them first.
This code could work for the full .Net Framework, but IsHandleCreated
doesn't exist under the Compact Framework.
Question: What should I use instead of IsHandleCreated
?
Control _parent; // set when custom BackgroundWorker like class is created
bool parentOk {
get {
if (_parent != null) {
if (!_parent.IsDisposed) {
return _parent.IsHandleCreated;
// Should I instead "return (_parent.Handle != IntPtr.Zero);"?
}
}
return false;
}
}
public void ReportProgress(int step, object data) {
lock (_thLock) {
if (parentOk && (ProgressChanged != null)) {
MethodInvoker methInvoker = delegate { ProgressChanged(step, data); };
try {
_parent.BeginInvoke(methInvoker); // recently changed from below
// _parent.Invoke(methInvoker); (old technique)
} catch (ObjectDisposedException) { // added for BeginInvoke
} catch (NullReferenceException err) {
Global.LogError(_CODEFILE + "ReportProgress", err);
} catch (InvalidOperationException err) {
Global.LogError(_CODEFILE + "ReportProgress", err);
}
}
}
}
An interesting (and not well documented that I've ever found) is that an Control's Handle isn't actually created until it is queried. It seems that in ost cases that happens internally to the framework just fine, but in cases where you are using a control for Invoking, there are occasions where it hasn't happened and you get an Invoke or BeginInvoke cannot be called on a control until the window handle has been created
Exception.
My solution has always been to query the handle directly early on. In your case you can probably get away with something like this (like your comment suggests):
bool ParentOk
{
get
{
return (_parent != null)
&& (!_parent.IsDisposed)
&& (_parent.Handle != IntPtr.Zero);
}
}