1

我的代码在不同于 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
    }
}

有什么建议么?

4

4 回答 4

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
        }));
    }
}
于 2012-07-19T16:30:46.993 回答
1

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

WinForms 采用这种方法的原因——使用 Control 或 Form 引用来访问使您能够在 UI 线程上运行代码的 Invoke 方法——是您必须在 UI 线程中运行代码的唯一原因是,如果您将编写/更改 UI 组件的状态。

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

于 2012-07-19T17:11:56.257 回答
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 = "";
}
}
于 2014-01-31T00:49:23.293 回答
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();
于 2014-04-21T09:31:03.497 回答