【问题标题】:Weird multithreading behavior in C#C# 中奇怪的多线程行为
【发布时间】:2013-04-30 11:06:42
【问题描述】:

我有一个监听线程函数,它等待传入的连接并为每个客户端启动一个新线程。每次启动新线程时,它都会写入“1”来记录:

void ListenWorkerDoWork(object sender, DoWorkEventArgs e) {
    try {
        var tcpListener = new TcpListener(IPAddress.Any, 843);
        tcpListener.Start();
        var worker = sender as BackgroundWorker;

        if (worker != null) {
            while (!worker.CancellationPending) {
                var client = tcpListener.AcceptTcpClient();
                var clientThread = new Thread(HandleClientComm) { IsBackground = true };
                clientThread.Start(client);
                Logger.Instance.WriteToLog(Logger.Type.Info, "1");
            }
        }
    } catch (Exception ex) {
        Logger.Instance.WriteToLog(Logger.Type.Error, string.Format("An error has occured while listening on port 843:{0}{1}", Environment.NewLine, ex));
    }
}

以及将“2”写入日志文件并处理传入连接的客户端处理线程:

private void HandleClientComm(object client) {
    Logger.Instance.WriteToLog(Logger.Type.Info, "2");
    [...]
}

我还有一个小应用程序,它每 50 毫秒连接一次服务器并发送/接收一些数据。如果我只启动一个客户端,那么“1”和“2”的数量是相等的,但是如果我在不同的计算机上启动多个客户端实例,那么“2”的数量比“1”高 5%。这意味着我的客户端线程的过程被调用的次数比实际请求的次数多 5%。怎么可能?例如,我有 3 个客户。每个客户端与服务器执行 1000 个会话。结果,我有:

  • 3000 次成功的客户端会话
  • 监听套接字接受的连接数为 3119(并写入“1”)
  • 客户端线程函数被调用了 3273 次

谢谢!

更新:

日志写入函数是线程安全的:

    public void WriteToLog(Type type, object message) {
        lock(writelock) {
            String str = typeText[(int)type] + DateTime.Now.ToString() + " : " + message.ToString();
            Console.WriteLine(str);
            if (stream != null) {
                stream.WriteLine(str);
                stream.Flush();
            }
        }
    }

【问题讨论】:

  • 如果你在接受TcpClient.Close之后关闭客户端连接会发生什么?
  • 我在 HandleClientComm(...) 中关闭连接
  • 您检查日志是否有错误?

标签: c# multithreading winsock


【解决方案1】:

重启 Visual Studio 并重建项目后问题自行解决。我不知道该说些什么。

【讨论】:

  • 呵呵——你不用说什么了:)
猜你喜欢
  • 2015-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-06
  • 1970-01-01
  • 2018-03-06
  • 1970-01-01
相关资源
最近更新 更多