Search code examples
multithreadingwindows-mobilecompact-framework

Exception when trying to show a form created in another (background) thread on .netCF with OAC


In a multi form .NetCF 3.5 application I'm trying create the forms in the background while the user is occupied with the previous form. We're using Orientation Aware Control in the project

We use a wrapper class (FormController) (please let me know if I'm using the wrong terminology) to keep static references to the different forms in our application. Since we only want to create them once.

At the moment the Forms are created the first time they are used. But since this is a time consuming operation we'd like to do this in the background while the user

Application.Run(new FormController.StartUI());

class FormController{

private static object lockObj = new object();
private static bool secIsLoaded = false;

private static StartForm startForm = new StartForm();
private static SecForm m_SecForm;
static SecForm FormWorkOrderList
{
    get
    {
            CreateSecForm();
            return m_SecForm;
        }
    }


private static void StartUI(){

    startForm.Show();

    ThreadStart tsSecForm = CreateSecForm;
    Thread trSecForm = new Thread(tsSecForm);
    trSecForm.Priority = ThreadPriority.BelowNormal;
    trSecForm.IsBackground = true;
    trSecForm.Start();
    return startForm;
}

private static void CreateSecForm()
{
    Monitor.Enter(lockObj);
    if(!secIsLoaded){
        m_SecForm = new SecForm();
        secIsLoaded = true;
    }
    Monitor.Exit(lockObj);
}

private static void GotoSecForm()
{
    SecForm.Show();
    StartForm.Hide();
}

When I call GotoSecForm() the program throws an excepton on SecForm.Show() with an exection with hResult: 2146233067 and no other valuable information.

The stacktrace of the exception is:

on Microsoft.AGL.Common.MISC.HandleAr(PAL_ERROR ar)
on System.Windows.Forms.Control.SuspendLayout()
on b..ctor(OrientationAwareControl control)
on Clarius.UI.OrientationAwareControl.ApplyResources(CultureInfo cultureInfo, Boolean skipThis)
on Clarius.UI.OrientationAwareControl.ApplyResources()
on Clarius.UI.OrientationAwareControl.OnLoad(EventArgs e)
on Clarius.UI.OrientationAwareControl.c(Object , EventArgs )
on System.Windows.Forms.Form.OnLoad(EventArgs e)
on System.Windows.Forms.Form._SetVisibleNotify(Boolean fVis)
on System.Windows.Forms.Control.set_Visible(Boolean value)
on System.Windows.Forms.Control.Show()

I'm quite qlueless about what's going wrong here. Can anyone help me out?

Or are there some better ways to load the forms in the background?

Let me know if any more information is needed.


Solution

  • You can't create forms (or safely do any manipulation of controls or forms) in background threads. They need to be created on the same thread that the message pump is running on - its just the way that Windows Forms work.

    Creating the form itself shouldn't be in itself an expensive task. My advice would be to perform any expensive computations needed to display the form in a background thread, and then pass the result of those computations back to the main message pump in order to create and display the form itself.

    (Half way through writing this I realised that this question is about windows mobile, however I'm 99% sure that the above still applies in this situation)