Winforms 获取WinForm“;“交叉线程操作无效”;仅当WCF主机应用程序在Visual Studio中运行时出错

Winforms 获取WinForm“;“交叉线程操作无效”;仅当WCF主机应用程序在Visual Studio中运行时出错,winforms,wcf,callback,Winforms,Wcf,Callback,我有一个WCF服务,我在WinForm应用程序中自我托管。在应用程序中,我有一个列表框控件来显示诊断信息。我将对ListBox控件的引用传递给WCF服务。在该服务中有一个使用它的回调 出于某种原因,如果我在Visual Studio之外运行应用程序,我可以使用列表框显示主宿主应用程序中的信息、WCF服务中的所有方法以及WCF服务中的单个回调。但是,在VisualStudio中运行时,同一应用程序在回调中尝试写入信息时失败 我是在做一些我根本做不到的事情,还是在VisualStudio中运行时发生

我有一个WCF服务,我在WinForm应用程序中自我托管。在应用程序中,我有一个列表框控件来显示诊断信息。我将对ListBox控件的引用传递给WCF服务。在该服务中有一个使用它的回调

出于某种原因,如果我在Visual Studio之外运行应用程序,我可以使用列表框显示主宿主应用程序中的信息、WCF服务中的所有方法以及WCF服务中的单个回调。但是,在VisualStudio中运行时,同一应用程序在回调中尝试写入信息时失败

我是在做一些我根本做不到的事情,还是在VisualStudio中运行时发生了一些不正确的事情

这是我的WinForm主机的一部分

    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中运行时

那么,我是否在做一些根本错误的事情