在socket编程中出现ContextSwitchDeadlock的问题
我要实现一个简单的服务器,其中主要的一段代码如下:
public void ServerThreadProc()
{
try
{
clientSocket = serverSocket.Accept();
//接收客户端发来的数据
byte[] recvBytes = new byte[1024];
int bytes = 0;
bytes = clientSocket.Receive(recvBytes, 0, clientSocket.Available, SocketFlags.None);
string strRequest = System.Text.Encoding.Unicode.GetString(recvBytes, 0, bytes);
ProcessParams(strRequest); //从strRequest中提取必要的参数
c.ConvertF(a,b); //a,b是类的成员变量,已在ProcessParams(strRequest)中提取了正确的值,c 是一个类的对象,其类型为另一dll中的某个类,这里通过c来访问该类中的Convert函数,Convert中调用了word的一些编程api
clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();
}
catch (Exception ex)
{
if (clientSocket.Connected)
{
clientSocket.Close();
}
}
现在遇到以下问题,上述的代码一直到执行完ProcessParams(strRequest)结果还是正确的.但执行到Convert函数中(注意Convert位于另一dll中)的调用Word编程api那一句时就出错了.出现了以下提示:
检测到 ContextSwitchDeadlock
Message: CLR 无法从 COM 上下文 0x196c58 转换为 COM 上下文 0x196ae8,这种状态已持续 60 秒。拥有目标上下文/单元的线程很有可能执行的是非泵式等待或者在不发送 Windows 消息的情况下处理一个运行时间非常长的操作。这种情况通常会影响到性能,甚至可能导致应用程序不响应或者使用的内存随时间不断累积。要避免此问题,所有单线程单元(STA)线程都应使用泵式等待基元(如 CoWaitForMultipleHandles),并在运行时间很长的操作过程中定期发送消息。
请不要告诉我要把调试->异常->Managed Debugging Assistant->ContextSwitchDeadlock的引发选项去掉,我试过了不是这个问题.也不要说把线程的ApartmentState设为ApartmentState.MTA,也不是这个原因导致的.
并且不要告诉我把c.ConvertF(a,b)的调用放在一个线程中,我也试过了,这样虽然可以,但由于此时会执行了clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();,搞到我不能向客户端发送执行的结果了.
我发现只有在clientSocket被close后,再执行ConvertF这个方法才会没有出错,但我必须在完成前不能关闭那个clientSocket,因为我还要把处理的结果发送会给客户端.请各位高手帮我解决一下这个问题.