简体   繁体   中英

C# - Splash Screen on Compact Framework

I'm trying to do a splash screen using CF.NET but I'm lost in the threading stuff.

What I have is a console project that dynamically loads (WinForm) screens (if exists, else output in Console).

What I want now is to be able to send messages to this form (running on a separate thread).

But this doesn't work, I cannot have a handle of my form in the current working thread.

This code works:

// Works but running in the current thread, so is blocking
// and that's not good
Assembly assembly = Assembly.LoadFrom("240x320Screens.dll");
Form ff = assembly.CreateInstance("Screens.Loader") as Form;
Application.Run(ff);
// The form implements this interface too
((ISplashView)ff).SetStep("Step 1 on 3");

Threaded code now (doesn't work):

Thread presenterThread = null;
Assembly assembly = Assembly.LoadFrom("240x320Screens.dll");
Form ff = assembly.CreateInstance("Screens.Loader") as Form;

presenterThread = new Thread((ThreadStart)(() => 
    {
        Application.Run(ff);
    }));
presenterThread.Start();

((ISplashView)ff).SetStep("Step 1 on 3");
Thread.Sleep(5000);
((ISplashView)ff).SetStep("Step 2 on 3");
Thread.Sleep(5000);
((ISplashView)ff).SetStep("Step 3 on 3");

// Wait the user close the launcher (allowed in my case)
if (presenterThread != null)
    presenterThread.Join();

But this throws :

Control.Invoke must be used to interact with controls created on a separate thread.

How can I fix this?

Thanks

The problem occurs because only the main UI thread is allowed to update UI controls. The way to get around this is to check the 'InvokeRequired' property on a control, create a delegate and execute the delegate using the control's Invoke method.

An easy implementation is to use the following static extension method:

public static void InvokeIfRequired<T>(this T control, Action<T> action) where T : Control
{
   if (control.InvokeRequired)
   {
      control.Invoke(action, control);
   }
   else
   {
      action(control);
   }
}

If you call it like so then everything will be handled for you:

this.textbox1.InvokeIfRequired(txt => txt.Text = "test");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM