2

メッセージのUDPポートをリッスンするC#メインウィンドウフォームがあります。目的のメッセージを受信すると、別のフォーム(ビデオフォーム)を起動します。このビデオフォームは、ビデオを再生する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があなたが間違ったことをしていると言うのを止めただけで、あなたが間違ったことをするのを止めませんでした. 例外の解釈が難しくなるというのは、実際の結果です。あなたはそれを手に入れることができてとても幸運でした。より一般的にはそれはちょっとうまくいきますが、プログラムをランダムで診断不可能な方法で失敗させます.

メイン スレッドでは、txtLog.Text の割り当てなど、UI に影響を与えるコードのみを呼び出す必要があります。新しいフォームの作成も、メイン スレッドでのみ行う必要があります。これを行うには、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 に答える