WCF(WPF)错误:调用线程必须是STA

时间:2013-07-25 13:08:43

标签: wpf multithreading wcf sta

我从服务参考中收到一些数据。

结构f.e.如下:
我从服务引用(名称空间:ServiceReference.Driver)中收到一些driverdata 我项目中driverdata的命名空间是'MyProject.Driver'。

应该在MyProject.Driver的构造函数中创建DriverUserControl。

public Driver(int id, string name, string telephone, string plate,
                  Dictionary<DateTime, TransportType> transportTypes, Division division)
    {
        this.id = id;
        this.name = name;
        this.telephone = telephone;
        this.plate = plate;
        this.transportTypes = transportTypes;
        this.division = division;
        userControl = new DriverUserControl(this);
    }

但是当我到达这里时:

public DriverUserControl(Driver magnet)
    {
        InitializeComponent();

        this.magnet = magnet;
        Render();
    }

每当它到达usercontrol的构造函数时,就会出现以下错误“调用线程必须是STA,因为许多UI组件需要这个”显示出来。

因为我从未在项目的任何地方创建过线程,所以我不知道应该如何将它设置为STA。我想服务引用被视为一个线程,但是,有没有办法将其更改为STA?

感谢。

1 个答案:

答案 0 :(得分:1)

您的控件如何实例化?它是在程序启动时创建的,还是在监听来自WCF服务的呼叫?

通常,WPF或winform应用程序的主线程已经是STA(如果搜索它,您将在代码生成的文件中找到应用于Main方法的STAThreadAttribute)

所以我怀疑你是为了响应传入的wcf调用而实例化你的控件。是吗?

如果是这种情况,则还有一个问题:Windows中的所有UI窗口都具有线程关联性,这意味着只允许创建它们的线程与它们通信。通常,仅通过从主线程创建窗口或控件来确保这一点。因此,后台线程不应该直接触及UI控件的成员。

因此,您需要确保从主线程创建用户控件。最简单的方法: 如果您已经可以访问将要放置用户控件的表单/窗口,只需使用:

TheWindowHostingTheControl.Dispatcher.Invoke (or BeginInvoke, or one of the AsyncInvokes), passing in a delegate to the code that instances your control.  that will cause the control to be created on the same thread that the host window has affinity for.  

每当来自Web服务的传入呼叫需要更新控件上的属性时,您都需要执行相同的操作(当然,您可以使用与控件关联的Dispatcher实例)。

这完全基于您正在响应传入的wcf调用的假设。 (对不起,如果我让你偏离轨道)。