ActiveX控件'6bf52a52-394a-11d3-b153-00c04f79faa6'无法实例化,因为当前线程不在单线程单元中

时间:2012-06-16 12:48:12

标签: c# multithreading

我有一个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?

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

设置运行axWindowsMediaPlayer1的帖子ApartmentState属性为ApartmentState.STA,如:

newThread.ApartmentState = ApartmentState.STA;

更好的方法是阅读MSDN。

希望对您有所帮助。