2010-01-24 93 views
1

我正在使用接收端的TcpListener和发送端的TcpClient编程简单的TCP文件传输。我有2个选项 - 同步或异步。如果我使用同步,我必须将发送/接收方法放入BackgroundWorker,以防止冻结GUI线程。异步版本没有问题...C#停止TCP文件传输

我的问题是,如何停止运行文件传输?

在synchronnous版本我试图用BackgroundWorker.CancelAsync()方法,并在每次循环检查BackgroundWorker.CancellationPending属性,但它似乎并不工作(CancelAsync可能是不设置CancellationPending属性):(

在异步版本中,我尝试使用volatile变量Indicator,并在每个Callback中检查其值。问题是,当我在Stop()方法中更改其值时,并且我在Callback中检查它,回调仍然读取其先前值:(

+0

volatile应该可以工作,但是您需要确保两个线程都指向相同的变量而不是两个不同的实例。也许你应该向我们展示代码。 – 2010-01-24 20:59:37

回答

1

CancelASync应该工作;您是否设置了:

backgroundWorker.WorkerSupportsCancellation = true: 
+0

当然。如果我没有,它会抛出一个例外,不是吗? – Klinki 2010-01-24 21:49:40

+0

哦,现在我知道它为什么不取消:)我在FormClosing事件中有BackgroundWorker.CancelAsync(),并且它没有设置CancellationPending属性,因为Form已经关闭:)现在我将e.Cancel添加到FormClosing事件中,工作:) – Klinki 2010-01-24 22:04:27

0

你是说当你检查时你没有阅读正确的“取消状态”?这表明你没有正确地同步你的线程之间的标志。

还是只是你不会检查“取消状态”,除非你收到一些新的数据? (从你描述你的tx/rx“循环”的方式来看,在同步和异步情况下,你将不得不接收一个新的数据报,然后你才有机会检查'取消'标志)

如果你在控制数据传输的两端,然后无论哪端(客户端或服务器)希望中止应理想情况下发送一个特殊的数据报到另一端停止传输 - 否则另一端将尝试继续发送/接收,不知道这一点它是独立的。所以或许一个更好的方法是实际发送/接收一个“取消传输”数据报,它将通知两端的TCP代码你想取消。 (即你不需要有一个特殊的取消标志,你只需检查你要发送的数据报或者刚收到的数据报是否是“取消传输”数据报)。这样可以让两端优雅而干净地关闭。

+0

这实际上是个好主意:)我虽然会捕获异常,当客户端关闭连接时,但这是更好的解决方案。它的简单,只需在发件人端将不同步的读入添加到NetworkStream中即可。而当它读取某个内容时,意味着客户端发送停止消息:)谢谢! – Klinki 2010-01-24 22:09:26

+0

您仍然需要捕捉异常(通信可能只是失败 - 一个好主意是在中间传输中拔掉网络电缆来测试您的最终代码),但允许端点谈判结论而不是仅仅拉动互相插入。 – 2010-01-25 09:14:55