Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.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
WPF:如何将数据从另一个域打包到用户控件_Wpf_Multithreading_Serialization_Cross Domain_Sta - Fatal编程技术网

WPF:如何将数据从另一个域打包到用户控件

WPF:如何将数据从另一个域打包到用户控件,wpf,multithreading,serialization,cross-domain,sta,Wpf,Multithreading,Serialization,Cross Domain,Sta,我必须使用其他应用程序域中的功能。结果应显示在用户控件中 我有这样的想法: var instance = domain.CreateInstanceFromAndUnwrap(...); instance.Foo(myWpfUserControl as ICallback); Foo(ICallback itf) { itf.SetData("..."); } WpfUserControl.SetData(string data) { if (!Dispatcher.CheckA

我必须使用其他应用程序域中的功能。结果应显示在用户控件中

我有这样的想法:

var instance = domain.CreateInstanceFromAndUnwrap(...);
instance.Foo(myWpfUserControl as ICallback);

Foo(ICallback itf) {
   itf.SetData("...");
}

WpfUserControl.SetData(string data)
{
   if (!Dispatcher.CheckAccess())
     Dispatcher.Invoke(...)
   ...
}  
我必须将[Serializable]属性放在WPFuserControl类上,并实现序列化构造函数和ISerializable接口,但现在我收到异常:

The calling thread must be STA because many UI components require this 
从UserControl()构造函数引发的

我该怎么做才能避免这种情况? 提前谢谢你

==============================

解决方案

正如@Al所注意到的,当涉及跨应用程序域调用时,我的用户控件必须序列化。现在我传递代理,它实现了ICallback接口。代理被标记为可序列化属性

代理实现应该完全不了解用户控件,因为应该再次尝试反序列化用户控件实例。当我试图通过界面从用户控件中提取代理时,它并没有帮助。当我试图将接口传递给代理(由用户控件实现)时,发生了相同的异常

最后,我将代理和用户控制与队列/信号量解耦。队列由一个工作线程监控,该线程将调用解除到用户控件


p、 此队列应从“MarshallByObjectRef”继承

如果异常来自构造函数,则表示您不是从UI线程创建此控件实例。这可以很好,但是在线程启动之前,必须通过调用Thread对象上的
.SetApartmentState(ApartmentState.STA)
来确保线程是STA线程

这也意味着您必须在线程对象启动之前访问它,因此您不能在线程池线程上执行此操作

不过,避免该问题的最佳方法可能是在主UI线程上创建控件,然后使用Dispatcher(或UiScheduler上的任务)分配文本值。这样,如果主线程需要设置、获取或绑定控件,也可以避免出现问题,因为如果控件是在另一个线程上创建的,则会导致跨线程异常

如果可能的话,我建议不要用这种方法来进行控制。这样做将生成一个新对象,该对象不会附加到任何面板或类似的面板,并且原始控件不会更新。遗憾的是,您不能从MarshalByRefObject继承Hirit,这将消除序列化,因为它只会将引用传递给另一个域


如果可以,单独调用Foo,然后将结果传递给原始Appdomain中的SetData

哦,不,这没有帮助。异常直接从UserControl构造函数引发。我猜它是处理域之间的序列化的哦,所以这个异常不是从这段代码中抛出的,而是从创建控件的地方抛出的?谢谢,@aL3891耐心等待。最后我找到了原因并找到了解决办法