我有一个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?
答案 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。
希望对您有所帮助。