C# - Compact Framework上的启动画面

时间:2011-03-01 11:01:00

标签: c# winforms multithreading

我正在尝试使用CF.NET进行启动画面,但我迷失在线程中。

我所拥有的是一个动态加载(WinForm)屏幕的控制台项目(如果存在,则在Console中输出)。

我现在想要的是能够向此表单发送消息(在单独的线程上运行)。

但这不起作用,我无法在当前工作线程中处理我的表单。

此代码有效:

// 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");

现在使用线程代码(不起作用):

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

但是这引发了:

  

必须使用Control.Invoke与在单独线程上创建的控件进行交互。

我该如何解决这个问题?

由于

1 个答案:

答案 0 :(得分:2)

出现此问题是因为只允许主UI线程更新UI控件。解决这个问题的方法是检查控件上的'InvokeRequired'属性,创建一个委托并使用控件的Invoke方法执行委托。

一个简单的实现是使用以下静态扩展方法:

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

如果您这样打电话,那么一切都将为您处理:

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