Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从其他线程(.net compact framework)正确创建控件,而不引用其他控件?_C#_.net_Winforms_Compact Framework - Fatal编程技术网

C# 如何从其他线程(.net compact framework)正确创建控件,而不引用其他控件?

C# 如何从其他线程(.net compact framework)正确创建控件,而不引用其他控件?,c#,.net,winforms,compact-framework,C#,.net,Winforms,Compact Framework,我的代码运行在与UI不同的线程中,它必须创建一个控件(windows窗体)。但是,我没有从UI中引用任何控件(这样,我可以使用myControl.Invoke(methodthattaddscoontroltoui))。在.net紧凑型框架中是否有这样做的方法 如果可能的话,我会对不使用其他控件引用的解决方案感兴趣(例如,跟踪所有创建的表单将不是一个好的解决方法,因为我的代码将在库中)。在完整的框架版本中,有Application.OpenForms属性,但这在CF中不存在 编辑: 此操作的主要

我的代码运行在与UI不同的线程中,它必须创建一个控件(windows窗体)。但是,我没有从UI中引用任何控件(这样,我可以使用
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();