我有一个文件传输应用程序(服务器 - 客户端)...在发送文件时,我想启用取消。
客户端取消后台工作者工作的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);
}
}
}
答案 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了。 它完全奏效了