2012-07-19 40 views
1

我有一个不同于UI的线程运行的代码,它必须创建一个控件(windows窗体)。但是,我没有提及UI的任何控件(这样,我可以使用myControl.Invoke(methodThatAddsControlToUI))。有没有办法做到这一点.net 紧凑框架?如果可能的话,我会对不使用其他控件引用的解决方案感兴趣(跟踪所有创建的表单,例如,将不是一个很好的解决方法,因为我的代码将位于库中)。在完整的框架版本中,有Application.OpenForms属性,但这不会在CF中退出。如何从其他线程(.net精简框架)正确创建控件,而不参考其他控件?

编辑:

这样做的主要目的是呼吁在UI线程的方法:

class Worker 
{ 
    public MyMethod() 
    { 
     // I need to call a method on the UI (this code doesn't run in the UI thread), 
     // but I don't have any field in this object holding an UI control 
     // value. So, I can't write myControlField.Invoke(...), 
     // but I still need to call a method on the UI thread 
    } 
} 

有什么建议?

+0

我可能失去了一些东西,但你有什么打算,如果你有没有其他的控制来分配其与新的控制做至? – 2012-07-19 15:30:15

+0

我想用它来调用UI上的方法,有点像newControl.Invoke(myMethod) – 2012-07-19 15:32:46

+1

你可以给我们一些代码示例吗?我很难理解你想要做什么!对于那个很抱歉。 – 2012-07-19 15:37:58

回答

2

从库中确实没有办法保证你的线程上下文,所以你最安全的选择是让消耗提供调用者并把它留给他们,以确保它是在适当的上下文中创建的。事情是这样的模式:

class Foo 
{ 
    private Control m_invoker; 

    public Foo() 
     : this(null) 
    { 
    } 

    public Foo(Control invoker) 
    { 
     if (invoker == null) 
     { 
      // assume we are created on the UI thread, 
      // if not bad things will ensue 
      m_invoker = new Control(); 
     } 
     else 
     { 
      m_invoker = invoker; 
     } 
    } 

    public void Bar() 
    { 
     m_invoker.Invoke(new Action(delegate 
     { 
      // do my UI-context stuff here 
     })); 
    } 
} 
1

我很抱歉,如果这不是一个真正的答案,但我认为它可以帮助:

之所以有WinForms的这种方法 - 使用控制或Form引用来访问一个Invoke方法,使您能够在UI线程上运行代码 - 是您必须在UI线程中运行代码的唯一原因是,如果您要编写/更改UI组件的状态。

当然,如果你打算这样做,你必须有一个UI组件的引用。所以你可以访问它的Invoke方法。我想不出任何其他原因,你必须从组件中访问UI线程,而不是修改视觉元素。

+0

是有意义的...意思是说,我会采取由ctacke建议的方法,并可能会重构我的应用程序解决这个问题...谢谢你的信息! – 2012-07-19 17:32:22

+0

我所知道的一个例子(因为我必须在OpenNETCF IoC库中处理它)是,如果一个库需要能够将事件引发给消费者,并且您想要这些事件,为了玩得很好,在UI线程中引发,你需要这个能力。您不会影响UI元素,但您可以让消费者接收事件,而无需执行自己的线程迁移。 – ctacke 2012-07-19 18:17:03

+0

@ctacke,我明白了,但我不确定它是否是最好的例子。如果这个库对这个UI一无所知,那就不是一个UI库,它不是将这些代码编组到UI中的责任。如果没有UI,该怎么办?也许你正在使用这个组件来构建一个服务。 – 2012-07-19 18:44:23

0

它必须被调用...但调用必须等待仍然主线程我的意思是你没有得到这样的错误,但这并不是简单的并行工作,如果你想在同一时间去多个进程只是创建更多然后一个线程

Thread thread = new Thread(new delegate_method(method)); 
thread.start(); 
Thread thread2 = new Thread(new delegate_method(method2)); 
thread.start(); 

处理两个过程同时

void method() 
{ 
//do something here -- working background Remember can not control any UI control from here 
finish_thread() 
} 

void method2() 
{ 
//do something here -- working background Remember can not control any UI control from here 
finish_thread() 
} 

void finish_thread() 
{ 
if(invoke.Required) 
{ 
//Here you have to call delegate method here with UI 
BeginInvoke(new delegate_method(finish_thread)); 
} 
else 
{ 
//Now you can control UI thread from here and also you finished background work 
//Do something working with UI thread 
textBox.Text = ""; 
} 
} 
0
//Declare this in class 
public delegate void delege(); 

//Write this lines when you want to background thread start 
    Thread thread = new Thread(new ThreadStart(() => { 
    //Do what you what with backgorund threading , can not use any interface comand here 
     BeginInvoke(new delege(() => { 
      //Do here any main thread thread job,this can do interface and control jobs without any error 
     })); 
    })); 
    thread.Start();