Winforms 获取WinForm“;“交叉线程操作无效”;仅当WCF主机应用程序在Visual Studio中运行时出错
我有一个WCF服务,我在WinForm应用程序中自我托管。在应用程序中,我有一个列表框控件来显示诊断信息。我将对ListBox控件的引用传递给WCF服务。在该服务中有一个使用它的回调 出于某种原因,如果我在Visual Studio之外运行应用程序,我可以使用列表框显示主宿主应用程序中的信息、WCF服务中的所有方法以及WCF服务中的单个回调。但是,在VisualStudio中运行时,同一应用程序在回调中尝试写入信息时失败 我是在做一些我根本做不到的事情,还是在VisualStudio中运行时发生了一些不正确的事情 这是我的WinForm主机的一部分Winforms 获取WinForm“;“交叉线程操作无效”;仅当WCF主机应用程序在Visual Studio中运行时出错,winforms,wcf,callback,Winforms,Wcf,Callback,我有一个WCF服务,我在WinForm应用程序中自我托管。在应用程序中,我有一个列表框控件来显示诊断信息。我将对ListBox控件的引用传递给WCF服务。在该服务中有一个使用它的回调 出于某种原因,如果我在Visual Studio之外运行应用程序,我可以使用列表框显示主宿主应用程序中的信息、WCF服务中的所有方法以及WCF服务中的单个回调。但是,在VisualStudio中运行时,同一应用程序在回调中尝试写入信息时失败 我是在做一些我根本做不到的事情,还是在VisualStudio中运行时发生
public WCFServiceHostGUI()
{
InitializeComponent();
// OutputBox is a ListBox control reference. Pass to WCF service to display diagnostics
WCFCallbacks.UsbBrokerService.initialize(OutputBox);
startService();
}
private void startService()
{
usbBrokerServiceHost = new ServiceHost(typeof(WCFCallbacks.UsbBrokerService));
ServiceDescription serviceDesciption = usbBrokerServiceHost.Description;
foreach (ServiceEndpoint endpoint in serviceDesciption.Endpoints)
{
OutputBox.Items.Add("Endpoint - address: " + endpoint.Address);
OutputBox.Items.Add(" - binding name: " + endpoint.Binding.Name);
OutputBox.Items.Add(" - contract name: " + endpoint.Contract.Name);
}
usbBrokerServiceHost.Open();
/*
ChannelFactory<WCFCallbacks.IUsbBroker> channelFactory = new ChannelFactory<WCFCallbacks.IUsbBroker>(BINDING, ADDRESS);
WCFCallbacks.IUsbBroker clientProxy = channelFactory.CreateChannel();
clientProxy.initialize(OutputBox);
*/
}
public WCFServiceHostGUI()
{
初始化组件();
//OutputBox是ListBox控件引用。传递到WCF服务以显示诊断
WCFCallbacks.UsbBrokerService.initialize(OutputBox);
startService();
}
私有void startService()
{
UsbBrokerService主机=新服务主机(typeof(WCFCallbacks.UsbBrokerService));
ServiceDescription ServiceDescription=usbBrokerServiceHost.Description;
foreach(ServiceDescription.Endpoints中的ServiceEndpoint端点)
{
OutputBox.Items.Add(“端点-地址:+Endpoint.address”);
添加(“-binding name:”+endpoint.binding.name);
OutputBox.Items.Add(“-contract name:+endpoint.contract.name”);
}
usbBrokerServiceHost.Open();
/*
ChannelFactory ChannelFactory=新的ChannelFactory(绑定,地址);
WCFCallbacks.IUsbBroker clientProxy=channelFactory.CreateChannel();
clientProxy.initialize(OutputBox);
*/
}
在构造函数中,对列表框的引用被传递给WCF服务。可以在startService()方法中看到通常创建的ServiceHost
下面是获取ListBox引用的WCF服务
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class UsbBrokerService : IUsbBroker
{
private static readonly List<IUsbBrokerCallback> subscribers = new List<IUsbBrokerCallback>();
private static ListBox OutputBox = null;
public UsbBrokerService()
{
Console.WriteLine("Service started");
UsbDevicePluginIndicator.DeviceNotify += new UsbDevicePluginIndicator.DeviceNotifyDelegate(UsbDevicePluginIndicator_DeviceNotify);
UsbDevicePluginIndicator.Start();
}
public static void initialize(ListBox outputBox)
{
OutputBox = outputBox;
}
public void AddMessage(string message)
{
// Use the following to see which endpoint is accessed
OperationContext oc = OperationContext.Current;
if (oc != null)
{
Console.WriteLine("A request was made on endpoint " + oc.Channel.LocalAddress.ToString());
if (OutputBox != null)
{
OutputBox.Items.Add("A request was made on endpoint " + oc.Channel.LocalAddress.ToString());
}
}
}
public bool RegisterDevices(UsbDevice[] usbDevices)
{
try
{
IUsbBrokerCallback callback = OperationContext.Current.GetCallbackChannel<IUsbBrokerCallback>();
if (!subscribers.Contains(callback))
{
subscribers.Add(callback);
}
return true;
}
catch
{
return false;
}
}
public bool UnRegisterDevices(UsbDevice[] usbDevices)
{
try
{
IUsbBrokerCallback callback = OperationContext.Current.GetCallbackChannel<IUsbBrokerCallback>();
if (subscribers.Contains(callback))
{
subscribers.Remove(callback);
}
return true;
}
catch
{
return false;
}
}
private void UsbDevicePluginIndicator_DeviceNotify(System.Windows.Forms.Message msg)
{
BroadcastHeader lBroadcastHeader;
Console.WriteLine("Wcf WM_DEVICECHANGE signaled");
if (OutputBox != null)
{
OutputBox.Items.Add("Wcf WM_DEVICECHANGE signaled");
}
}
}
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
公共类UsbBrokerService:IUsbBroker
{
私有静态只读列表订阅者=新列表();
私有静态列表框OutputBox=null;
公共UsbBrokerService()
{
Console.WriteLine(“服务已启动”);
UsbDevicePluginIndicator.DeviceNotify+=新的UsbDevicePluginIndicator.DeviceNotifyLegate(UsbDevicePluginIndicator_DeviceNotify);
UsbDevicePluginIndicator.Start();
}
公共静态无效初始化(列表框输出框)
{
OutputBox=输出框;
}
公共无效添加消息(字符串消息)
{
//使用以下命令查看访问哪个端点
OperationContext oc=OperationContext.Current;
如果(oc!=null)
{
WriteLine(“在端点“+oc.Channel.LocalAddress.ToString()”上发出了请求);
如果(输出框!=null)
{
OutputBox.Items.Add(“在端点“+oc.Channel.LocalAddress.ToString()上发出了请求”);
}
}
}
公共布尔注册设备(USB设备[]USB设备)
{
尝试
{
IUSBrokerCallback callback=OperationContext.Current.GetCallbackChannel();
如果(!subscribers.Contains(回调))
{
添加(回调);
}
返回true;
}
接住
{
返回false;
}
}
公共bool注销设备(USB设备[]USB设备)
{
尝试
{
IUSBrokerCallback callback=OperationContext.Current.GetCallbackChannel();
if(subscribers.Contains(回调))
{
删除(回调);
}
返回true;
}
接住
{
返回false;
}
}
专用void UsbDevicePluginIndicator_devicentify(System.Windows.Forms.Message msg)
{
广播报头;
控制台写入线(“Wcf WM_设备更改信号”);
如果(输出框!=null)
{
OutputBox.Items.Add(“Wcf WM_设备更改信号”);
}
}
}
在回调例程UsbDevicePluginIndicator_设备中,验证写入OutputBox的尝试失败,并显示“跨线程操作无效:控件“OutputBox”是从创建它的线程以外的线程访问的。”但仅在Visual Studio中运行时
那么,我是否在做一些根本错误的事情