c# - 线程正在退出

标签 c# multithreading sockets

我有一个线程的小问题。我执行函数 Receive,超时设置为 600,但它在这里结束

if ((thr.ThreadState != ThreadState.Running) 
    && (thr.ThreadState != ThreadState.WaitSleepJoin))
{
  ThreadState st = thr.ThreadState;
  lg.WriteString("EXIT BY THREAD END");
  lg.WriteString("LAST: "+st.ToString());
  break;
}

只有当线程结束并且我已经收到所有数据时,该函数才应该在那里结束,但是当我打开文件 errores.txt 时,我看到 ThreadState 值为 Running 或 WaitSleepJoin。

知道函数为什么会中止吗?

下面有更多代码->

bool exit = false;
void WaitAndRead() {
if (buffer == null)
  buffer = new List<byte>();
buffer.Clear();
try
{
  while (sock_client.Available < 1 && !exit)
    Thread.Sleep(10);
  while (sock_client.Available > 0 && !exit)
  {
    byte[] b = new byte[sock_client.Available];
    sock_client.Receive(b, 0, b.Length, SocketFlags.None);
    buffer.AddRange(b);
    Thread.Sleep(25);
  }
}
catch (Exception ex) 
{ 
  Log lg = new Log("C:\\TPV\\errores.txt"); 
  lg.WriteException(ex, true); 
}

public int Receive(int timeout,out List<byte> result) 
{
  result = new List<byte>();
  try
  {
    if (!Connected)
      return NOT_CONNECTED;
    bool ok = true;
    ThreadStart str = delegate 
    {
      try { WaitAndRead(); }
      catch (Exception ex) 
      { 
        Log lg = new Log("C:\\TPV\\errores.txt"); 
        lg.WriteException(ex, true); ok = false; }
      };
      exit = false;
      Thread thr = new Thread(str);
      thr.Start();
      int x = 0;
      int max = 10 * timeout;
      while (x < max)
      {
        Log lg = new Log("C:\\TPV\\errores.txt");
        if ((thr.ThreadState != ThreadState.Running) 
            && (thr.ThreadState != ThreadState.WaitSleepJoin))
        {
          ThreadState st = thr.ThreadState;
          lg.WriteString("EXIT BY THREAD END");
          lg.WriteString("LAST: "+st.ToString());
          break;
        }
        x++;
        Thread.Sleep(10);
      }
      exit = true;
      if (x >= max)
        return Timeout;
      result = new List<byte>(buffer.ToArray());
      return ok?OK:NOT_CONNECTED;
    }
    catch(Exception ex) 
    {
      Log lg = new Log("C:\\TPV\\errores.txt"); 
      lg.WriteException(ex, true);
      return NOT_CONNECTED;
    }
  }

最佳答案

ThreadState 属性的值可能会在这段代码求值时发生变化:

if ((thr.ThreadState != ThreadState.Running) && (thr.ThreadState != ThreadState.WaitSleepJoin))
{
    ThreadState st = thr.ThreadState;
    lg.WriteString("EXIT BY THREAD END");
    lg.WriteString("LAST: "+st.ToString());
    break;
}

考虑以下场景:

  1. thr.ThreadStateWaitSleepJoin
  2. if 语句的第一部分评估为 true
  3. thr.ThreadState 在评估 if 的第二部分之前更改为 Running
  4. if 语句的第二部分评估为 true
  5. 由于两个部分的计算结果都为 true,因此进入了 if block

您可以尝试重写代码,如下所示,这样您只检查一次 ThreadState 属性的值:

var state = thr.ThreadState;
if (state != ThreadState.Running && state != ThreadState.WaitSleepJoin)
{
    lg.WriteString("EXIT BY THREAD END");
    lg.WriteString("LAST: "+ state.ToString());
    break;
}

关于c# - 线程正在退出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9083848/

相关文章:

c# - 基于当前日期和时间的 Div 背景颜色

java - 从本地机器上的多个线程通过 RMI 调用线程安全方法是否安全?

c++ - 第一次发送后未立即生成 SIGPIPE

C++在从发送的同一端口上接收UDP数据包

c# - 连接的服务组件 Microsoft WCF Web 服务引用提供程序失败。(HRESULT : 0x80131500) the project format is incorrect

C# 可变数组项?

c# - 正则表达式重复组

java - 单独线程中的屏幕捕获导致 Java 应用程序缓慢/无响应

c++ - OpenMP:如何处理全局标准 vector 上的竞争条件

javascript - 在 AngularJs 中使用 socket.io 进行用户更新时出现错误