2

我有一个 C# 主窗口窗体,它侦听 UDP 端口以获取消息。收到所需消息后,它将启动另一个表单(视频表单)。此视频表单包含一个将播放视频的 axWindowsMediaPlayer1。

但是每当它接收到启动视频表单的消息时,它都会收到一个 UDP 错误“ActiveX 控件 '6bf52a52-394a-11d3-b153-00c04f79faa6' 无法实例化,因为当前线程不在单线程单元中。”

    private void initCommunication()
    {
        CheckForIllegalCrossThreadCalls = false;
        try
        {                

            // For receiving messages
            //We are using UDP sockets
            serverSocket = new Socket(AddressFamily.InterNetwork,
                SocketType.Dgram, ProtocolType.Udp);

            //Assign the any IP of the machine and listen on port number 
            IPEndPoint ipEndPoint2 = new IPEndPoint(IPAddress.Any, listeningPort);

            //Bind this address to the server
            serverSocket.Bind(ipEndPoint2);

            IPEndPoint ipeSender = new IPEndPoint(IPAddress.Any, 0);
            //The epSender identifies the incoming clients
            EndPoint epSender = (EndPoint)ipeSender;

            //Start receiving data
            serverSocket.BeginReceiveFrom(byteData, 0, byteData.Length,
                SocketFlags.None, ref epSender, new AsyncCallback(OnReceive), epSender);

        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "UDP Error",
                MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

    #region UDP OnReceive
    private void OnReceive(IAsyncResult ar)
    {
        try
        {
            IPEndPoint ipeSender = new IPEndPoint(IPAddress.Any, 0);
            EndPoint epSender = (EndPoint)ipeSender;

            serverSocket.EndReceiveFrom(ar, ref epSender);

            //Transform the array of bytes received from the user into an
            //intelligent form of object Data
            Data msgReceived = new Data(byteData);

            switch (msgReceived.strMessage)
            {
                case "1":
                    btnPlayVideo_Click(null,null);
                    break;                    
            }               

            txtLog.Text += msgReceived.strName + " : " + msgReceived.strMessage + "\r\n";
            txtLog.SelectionStart = txtLog.Text.Length;
            txtLog.ScrollToCaret();
            serverSocket.BeginReceiveFrom(byteData, 0, byteData.Length, SocketFlags.None, ref epSender,
                    new AsyncCallback(OnReceive), epSender);

        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "UDP OnReceive Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }
    #endregion

此行中抛出错误 axWindowsMediaPlayer1 = new AxWMPLib.AxWindowsMediaPlayer();

我在网上搜索过,如何创建 STA?

4

3 回答 3

2

[STAThread]属性添加到您的Main方法中。

于 2012-06-16T12:50:37.010 回答
1

您的主要问题是 serverSocket.BeginReceiveFrom() 的回调在线程池线程上运行。您可能已经收到了强烈的警告,它使您将 CheckForIllegalCrossThreadCalls 设置为 false。这不是一件明智的事情,它只是阻止 Winforms 告诉你做错了,它并没有阻止你做错。结果确实越来越难以解释异常。你很幸运能得到一个,更典型的是它有点工作,但然后让你的程序以随机​​和无法诊断的方式失败。

您只能在主线程上调用影响 UI 的代码,例如 txtLog.Text 分配。创建新表单也应该只在主线程上完成。在 OnReceive() 回调中使用主窗体的 BeginInvoke() 方法(或 txtLog.BeginInvoke 方法)来完成。

于 2012-06-16T13:49:29.807 回答
0

设置运行axWindowsMediaPlayer1的线程ApartmentState属性ApartmentState.STA如下:

newThread.ApartmentState = ApartmentState.STA;

更好的方法是阅读 MSDN。

希望这对您有所帮助。

于 2013-02-26T15:49:13.017 回答