Search code examples
c#.netwindows-mobilecompact-framework

Test Control Handle under Mobile .Net CF


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);
      }
    }
  }
}

Solution

  • 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);
        }
    }