我的代码运行在与UI不同的线程中,并且必须创建一个控件(windows窗体)。但是,我没有从UI的任何控件的引用(这样,我可以使用myControl.Invoke( methodThatAddsControlToUI )
)。有没有办法在.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
}
}
有什么建议吗?
答案 0 :(得分: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 :(得分:1)
如果这不是真正的答案,我很抱歉,但我认为这可能有所帮助:
WinForms之所以采用这种方法 - 使用Control或Form引用访问一个允许您在UI线程上运行代码的Invoke方法 - 是您必须在UI中运行代码的唯一原因如果您要编写/更改UI组件的状态,则为Thread。
当然,如果您要这样做,您必须具有对UI组件的引用。所以你可以访问它的Invoke方法。我想不出除了修改可视元素之外你必须从组件访问UI线程的任何其他原因。
答案 2 :(得分: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 = "";
}
}
答案 3 :(得分: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();