Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 挂起和恢复线程的其他方法有哪些?_C#_.net 2.0_Thread Safety - Fatal编程技术网

C# 挂起和恢复线程的其他方法有哪些?

C# 挂起和恢复线程的其他方法有哪些?,c#,.net-2.0,thread-safety,C#,.net 2.0,Thread Safety,这两种方法Thread.Suspend()和Thread.Resume()自.NET 2.0以来已过时。为什么?还有什么其他的选择和例子吗?这是有史以来最好的线程教程(对于C#): 对于wait,您需要在线程上使用.Join()。这将等到胎面光洁度完成作业。其他方面,您需要使用。好的替代方案都是在线程到达愿意等待的点时起作用的。挂起是危险的,因为它可以在线程持有互斥锁时挂起线程——这是死锁的一种方法 因此,线程需要的是一个可以等待的ManualResetEvent,它可以在安全的情况下等待,也可

这两种方法
Thread.Suspend()
Thread.Resume()
自.NET 2.0以来已过时。为什么?还有什么其他的选择和例子吗?

这是有史以来最好的线程教程(对于C#):


对于wait,您需要在线程上使用.Join()。这将等到胎面光洁度完成作业。其他方面,您需要使用。

好的替代方案都是在线程到达愿意等待的点时起作用的。挂起是危险的,因为它可以在线程持有互斥锁时挂起线程——这是死锁的一种方法


因此,线程需要的是一个可以等待的ManualResetEvent,它可以在安全的情况下等待,也可以在没有任何锁的情况下等待。

我同意这是一个很好的教程。Suspend()和Resume()过时的主要原因是它们是非常危险的方法。在任何时候,线程t都可以做任何事情。任何东西假设你的线程正在读取一个文件,并且锁定了它。你挂起你的线程。文件保持锁定状态。其他资源也是如此。互斥锁也是如此。

那个太长了。我需要的是一个快速的例子代码使用。我从讨论中找到了一个答案,由马克·R·道森在回答。它解释了过时方法的危险,以及如何使用AutoResteEvent通知第二个线程继续处理。

您需要使用AutoResteEventWaitHandle

假设你想做这样的事情(注意:不要这样做!):

正如其他人所说,这是一个坏主意。即使只在自己的线程上使用Suspend是相对安全的,但您永远无法确定在线程实际挂起时是否调用Resume。因此,暂停和恢复已被淘汰

相反,您希望使用AutoResetEvent:

private EventWaitHandle wh = new AutoResetEvent();

private void WorkerThread() 
{
    while(true) 
    {
        wh.WaitOne();
        //Do work.
    }
}

public void StartWorking()
{
    wh.Set();
}

工作线程将在等待句柄上等待,直到另一个线程调用StartWorking。它的工作原理与Suspend/Resume非常相似,因为AutoResetEvent只允许一个线程“恢复”

您可以使用手动重置而不是自动重置:

public class Worker
{
 ManualResetEvent _shutdownEvent = new ManualResetEvent(false);
 ManualResetEvent _pauseEvent = new ManualResetEvent(true);
 Thread _thread;

public Worker() { }

public void Start()
 {
 _thread = new Thread(DoWork);
 _thread.Start();
 Console.WriteLine("Thread started running");
 }

public void Pause()
 {
 _pauseEvent.Reset();
 Console.WriteLine("Thread paused");
 }

public void Resume()
 {
 _pauseEvent.Set();
 Console.WriteLine("Thread resuming ");
 }

public void Stop()
 {
 // Signal the shutdown event
 _shutdownEvent.Set();
 Console.WriteLine("Thread Stopped ");

// Make sure to resume any paused threads
 _pauseEvent.Set();

// Wait for the thread to exit
 _thread.Join();
 }

public void DoWork()
 {
 while (true)
 {
 _pauseEvent.WaitOne(Timeout.Infinite);

if (_shutdownEvent.WaitOne(0))
 break;

// Do the work..
 Console.WriteLine("Thread is running");

 }
 }
}

Thread.Suspend()
Thread.Resume()
在.NET中过时或被删除的原因与
Thread.Suspend()
Thread.Resume()
在Java中过时的原因大致相同。比较-

  • Java的(
    suspend
    “天生容易死锁”),具有
  • MarkR.Dawson的(“如果在执行过程中停止线程,则可能会遇到死锁和争用情况”)
解决方案: 让一个线程仅在另一个线程挂起自身时恢复另一个线程。 因此,第一个线程仅在另一个线程挂起自己(即,其ThreadState=suspended)时才恢复另一个线程,从而使自己准备好恢复。这似乎是安全和完美的


或者,我不了解.Net线程吗?

手动重置事件的优点。您还可以使用AutoResetEvent。这解决了典型的挂起/恢复情况,并避免了过时的警告。这意味着您必须将线程逻辑放入线程中。suspend resume允许您编写代码,而不需要任何线程。@zespri:uh,怎么写
Suspend()
Resume()
Thread
类中与线程相关的方法。它们是不好的方法,因为终止进程比要求停止进程更糟糕。@siride您应该始终努力实现模块化。如果您能够以一种您的工作线程根本不需要执行任何线程管理和调用
thread
类上的任何方法的方式编写代码,那么您已经做得很好了。将所有线程管理代码隔离在工作线程之外是理想的——不幸的是,这通常是不可能实现的
Suspend
/
Resume
特别是在可能的情况下,这是一种场景。@zespri:事实上,事件更抽象。(1) 它们根本不必与线程一起使用。(2) 他们回答的问题是“某个条件是真的,我可以继续吗?”而没有提及条件是否已设置。(3) Suspend/Resume只能与线程一起使用,因此它们实际上根本不提供对线程的抽象。尝试了这个方法后,它就不起作用了。我在_pauseEvent.WaitOne行上放置了一个断点,按下F10键后,它转到下一行并继续运行线程。
public class Worker
{
 ManualResetEvent _shutdownEvent = new ManualResetEvent(false);
 ManualResetEvent _pauseEvent = new ManualResetEvent(true);
 Thread _thread;

public Worker() { }

public void Start()
 {
 _thread = new Thread(DoWork);
 _thread.Start();
 Console.WriteLine("Thread started running");
 }

public void Pause()
 {
 _pauseEvent.Reset();
 Console.WriteLine("Thread paused");
 }

public void Resume()
 {
 _pauseEvent.Set();
 Console.WriteLine("Thread resuming ");
 }

public void Stop()
 {
 // Signal the shutdown event
 _shutdownEvent.Set();
 Console.WriteLine("Thread Stopped ");

// Make sure to resume any paused threads
 _pauseEvent.Set();

// Wait for the thread to exit
 _thread.Join();
 }

public void DoWork()
 {
 while (true)
 {
 _pauseEvent.WaitOne(Timeout.Infinite);

if (_shutdownEvent.WaitOne(0))
 break;

// Do the work..
 Console.WriteLine("Thread is running");

 }
 }
}