2012-06-16 39 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。

希望對你有所幫助。

相關問題