C# 如何从其他线程(.net compact framework)正确创建控件,而不引用其他控件?
我的代码运行在与UI不同的线程中,它必须创建一个控件(windows窗体)。但是,我没有从UI中引用任何控件(这样,我可以使用C# 如何从其他线程(.net compact framework)正确创建控件,而不引用其他控件?,c#,.net,winforms,compact-framework,C#,.net,Winforms,Compact Framework,我的代码运行在与UI不同的线程中,它必须创建一个控件(windows窗体)。但是,我没有从UI中引用任何控件(这样,我可以使用myControl.Invoke(methodthattaddscoontroltoui))。在.net紧凑型框架中是否有这样做的方法 如果可能的话,我会对不使用其他控件引用的解决方案感兴趣(例如,跟踪所有创建的表单将不是一个好的解决方法,因为我的代码将在库中)。在完整的框架版本中,有Application.OpenForms属性,但这在CF中不存在 编辑: 此操作的主要
myControl.Invoke(methodthattaddscoontroltoui)
)。在.net紧凑型框架中是否有这样做的方法
如果可能的话,我会对不使用其他控件引用的解决方案感兴趣(例如,跟踪所有创建的表单将不是一个好的解决方法,因为我的代码将在库中)。在完整的框架版本中,有Application.OpenForms
属性,但这在CF中不存在
编辑:
此操作的主要目的是在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
}
}
有什么建议吗?从库中确实无法保证您的线程上下文,因此您最安全的方法是让使用者提供调用程序,并将其留给他们,以确保它是在正确的上下文中创建的。类似这样的模式:
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
}));
}
}
如果这不是一个真实的回答,我很抱歉,但我认为这可能会有帮助: WinForms采用这种方法的原因是——使用控件或表单引用访问使您能够在UI线程上运行代码的调用方法——您必须在UI线程中运行代码的唯一原因是您是否要编写/更改UI组件的状态
当然,如果要这样做,必须有对UI组件的引用。所以您可以访问它的Invoke方法。除了修改可视元素之外,我想不出还有什么其他原因需要从组件访问UI线程 它必须是调用。。。但调用必须等待主线程,我的意思是,您不会以这种方式得到错误,但这不是并行工作,如果您想同时执行多个进程,只需创建多个线程
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 = "";
}
}
我可能遗漏了一些东西,但是如果你没有其他控件可以分配给你,你会怎么处理这个新控件呢?我想用它来调用UI上的一个方法,比如newControl.invoke(myMethod)你能给我们一些代码示例吗?我很难理解你想做什么!很抱歉。也许您正在寻找Dispatcher()?这是CF吗@MattRazza,dispatcher是WPF组件,而不是WinForms。()是有意义的…同时,我将采用ctacke建议的方法,并可能在以后重构我的应用程序以解决此问题。。。无论如何,谢谢你的信息!我知道的一个例子(因为我必须在OpenNETCF IoC库中处理它)是,如果库需要能够向使用者引发事件,并且为了更好地播放,您希望这些事件在UI线程上引发,那么您需要此功能。您没有影响UI元素,但您允许使用者接收事件,而不必自己进行线程迁移。@ctacke,我明白了,但不确定这是否是最好的示例。如果这个库对UI一无所知,也就是说,它不是一个UI库,那么它就没有责任将代码封送到UI。如果没有用户界面怎么办?也许你正在使用这个组件来构建一个服务。我并不是在批评@ctacke的回答,因为我实际上打算提出同样的建议,但我必须提醒你,使用这种方法意味着你的库——不管它是什么——现在显式地依赖于用户界面,所以请确保这是你想要的。你刚刚减少了它的重用可能性…@Igomide,这里是一个好的开始:。
//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();