0

我有一个文件传输应用程序(服务器-客户端)......在发送文件时,我想启用取消。
客户端取消它由后台工作者工作的 SendFile 方法,然后它向服务器发送命令以取消其接收线程。
当服务器收到此命令时,它调用Stop 方法,但它停留在该行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);
                }
            }
      }
4

3 回答 3

1

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

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

于 2012-03-10T07:10:14.997 回答
1

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

如果正在中止的线程位于代码的受保护区域(例如 catch 块、finally 块或受约束的执行区域)中,则调用 Abort 的线程可能会阻塞。如果调用 Abort 的线程持有被中止线程所需的锁,则可能发生死锁。

于 2012-03-10T07:37:21.253 回答
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了。它完全有效

于 2012-03-10T08:52:52.373 回答