我有一个侦听通过流发送数据的方法。因为networkstream.read方法是同步的,我必须在一个单独的线程上执行它。所以我在一个单独的线程上执行的方法是:
void someMethod(param1, param2....)
{
try{
while( stream.read(data...) != 0 ) // code waits here until data is received
{
// do stufff
}
}catch{}//
}
我能够退出该线程的唯一方法是关闭流并执行catch块。我有时需要开始在同一个流上侦听数据,但是使用不同的方法。所以如果我创建线程为Thread t = new Thread(new threadstart(somemethod ......)然后执行t.start(someObject);稍后当我执行t.abort()时;该方法仍然会监听数据。如何终止它?
我也尝试过创建一个全局变量,例如:
bool someBoolean = false;
void someMethod(param1, param2....)
{
try{
while(someBoolean ==false && stream.read(data...) != 0 ) // code waits here until data is received
{
// do stufff
}
}catch{}//
}
然后我想我将someBoolean改为true,该方法将停止执行。由于某种原因,它没有。为什么?貌似someBoolean是一次两个变量。因为从主线程更改其值似乎不会影响它在第二个线程...
答案 0 :(得分:1)
我想线程可能是abortet但是那个线程的资源(因为流而不受管理)将不会被释放 - 这就是你的问题。
不要中止线程 - 永远不要。
请停止尝试将stream.read的异步版本与CancellationToken一起使用。 如果你给我们更多的信息(什么流? - 读是奇怪的(“R”ead?),线程的开始)我可能会尝试给你更多的细节。
PS:尝试使用System.Threading.Task代替线程 - 使用起来更好。
作为一个没有进一步信息的快速修复,您可以尝试这样的事情:
ManualThreadEvent terminate = new ManualThreadEvent(false);
bool someBoolean = false;
void someMethod(param1, param2....)
{
try{
// wait for enough data or for termination:
while(terminate.WaitOne(100) == false && stream.DataAvaiable <= bytesNeeded)
{ /* nothing to do here */ }
if (terminate.WaitOne(0)) return; // terminate on request
// To your stuff with read
}catch{}//
}
void Terminate()
{
terminate.Set();
}
答案 1 :(得分:1)
我该如何终止它?
解除阻塞流调用的标准协议是关闭流并捕获异常。中断读取只是为了将其移到另一种方法是相当不寻常的。如果您觉得这仍然是必要的,那么您应该在读取操作上提供额外的间接级别。当使用BeginRead
之类的异步调用而不是同步调用时,处理这样的场景要容易得多。通过Thread.Abort
终止线程可能会导致比解决的问题更多的问题。
然后我想我将someBoolean更改为true,该方法将停止 执行。由于某种原因,它没有。为什么?它看起来像someBoolean 一次是两个变量。因为从主要改变它的价值 线程似乎没有影响它在第二个线程...
缺少内存屏障可能会导致此问题,但更可能的原因是线程卡在Read
内并且实际上并没有按照您希望的方式读取someBoolean
会。