2012-06-16 40 views
1

我有一个C#主窗口窗口,它监听UDP端口的消息。收到所需信息后,它将启动另一个表单(视频表单)。这个录像带由一个可以播放视频的axWindowsMediaPlayer1组成。ActiveX控件'6bf52a52-394a-11d3-b153-00c04f79faa6'不能实例化,因为当前线程不在单线程公寓

但是无论何时它收到消息启动视频窗体,它将收到一个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 =新AxWMPLib.AxWindowsMediaPlayer(;

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

回答

2

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

+0

我的主要方法已经有[STAThread]了。默认情况下,由C#窗体窗体创建的program.cs已经有了它... – humansg

+0

@humansg然后哪个线程引发这个异常? –

+0

可能是异步udp线程? – humansg

1

您的主要问题是serverSocket.BeginReceiveFrom()的回调在线程池线程上运行。您可能已经得到了强烈的警告,它使您将CheckForIllegalCrossThreadCalls设置为false。这不是一个明智的做法,它只是阻止Winforms告诉你做错了,它并没有阻止你做错了。更难以解释例外的确是结果。你很幸运得到一个,更通常它有点作品,但随后使你的程序失败,随机和undiagnosable方式。

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

+0

但即使我不更新txtLog.Text,错误仍然会发生。 – humansg

+1

当然,但我们无法看到您在btnPlayVideo_Click()中所做的操作。我的水晶球说:我敢打赌,他在该代码中创建了一种新形式。其中有一个ActiveX控件说“你创建了我的错误线程!!!”。你做到了。 –

+0

是的,你的水晶球是对的!右边是一个按钮,它将启动一个mediaplayer ActiveX控件的视频。如果我在物理上点击鼠标,它就会起作用。但是,当我通过UDP远程调用进行操作时,它不起作用。我应该如何在主窗体线程上启动视频窗口? – humansg

0

设置运行的axWindowsMediaPlayer1的线程ApartmentState性质是ApartmentState.STA这样的:

newThread.ApartmentState = ApartmentState.STA; 

更好的方法是阅读MSDN。

希望对你有所帮助。

相关问题