我从服务参考中收到一些数据。
结构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?
感谢。
答案 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调用的假设。 (对不起,如果我让你偏离轨道)。