停止线程不起作用

时间:2011-08-31 16:19:22

标签: c# multithreading

我有一个侦听通过流发送数据的方法。因为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是一次两个变量。因为从主线程更改其值似乎不会影响它在第二个线程...

2 个答案:

答案 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会。