Thread.Abort()陷入了NetworkStream.Read?

时间:2012-03-10 07:00:37

标签: c# cancellation thread-abort

我有一个文件传输应用程序(服务器 - 客户端)...在发送文件时,我想启用取消。
客户端取消后台工作者工作的SendFile方法,然后向服务器发送命令取消其接收线程。
当服务器收到此命令时,它调用停止方法,但它停留在该行 network.Read(data,0,data.Length);

我怎样才能中止这个帖子然后去最后而不会卡在network.Read(..)??
提前谢谢。

Thread thTransferFile = null;

void Start()
{
    thTransferFile = new Thread(unused => ft.Receive(destPath, Convert.ToInt64(fileSize);
    thTransferFile.Start();
}

void Stop()
{
    thTransferFile.Abort();
}


public void Receive(string destPath, long fileSize)
    {
        using (fs = new FileStream(destPath, FileMode.Create, FileAccess.Write))
        {
            try
            {
                int count = 0;
                long sum = 0;
                data = new byte[packetSize];
                while (sum < fileSize)
                {
                    count = network.Read(data, 0, data.Length);   //thread stucks in this line when i abort it
                    fs.Write(data, 0, count);
                    sum += count;
                }
            }
            finally
            {
                network.Write(new byte[1], 0, 1); //tell client that the file transfer ends
                network.Flush();
                fs.Dispose();
                if (Thread.CurrentThread.ThreadState == ThreadState.AbortRequested)
                {
                    File.Delete(destPath);
                }
            }
      }

3 个答案:

答案 0 :(得分:1)

而不是中止线程,Close() network。它将像您期望的那样抛出异常。

杀死线程是一个很大的禁忌,因为有些资源可以不清理......

答案 1 :(得分:1)

NetworkStream.Read被阻止,直到它收到数据。使用NetworkStream的ReadTimeout Read the community comment设置读取操作的超时。此外,您可能想重新考虑使用Abort()来杀死您的线程。在while循环中添加一个布尔标志,并在调用Stop()时将该标志设置为false。此停止标志与ReadTimeout结合将确保您的程序最终退出。

  

调用Abort的线程可能会阻塞正在进行的线程   中止是在受保护的代码区域中,例如catch块,   最后阻塞或约束执行区域。如果线程那个   调用Abort持有一个被中止线程需要的锁,一个死锁   可能会发生。

答案 2 :(得分:0)

我找到了解决方案 当我取消从客户端发送.. network.DataAvailable设置为false ..所以我将此行添加到我在服务器中的接收方法

在while循环中

                while (sum < fileSize)
                {
                    if (network.DataAvailable)
                    {
                        count = network.Read(data, 0, data.Length);
                        fs.Write(data, 0, count);
                        sum += count;
                    }
                }

所以它永远不会停留在network.Read了。 它完全奏效了