【问题标题】:C# Threading.Suspend in Obsolete, thread has been deprecated?C# Threading.Suspend 已过时,线程已被弃用?
【发布时间】:2010-12-22 12:16:55
【问题描述】:

在我的应用程序中,我正在通过另一个线程(其他那个 GUI 线程)执行我的文件读取。有两个按钮分别暂停和恢复线程。

private void BtnStopAutoUpd_Click(object sender, EventArgs e)
        {
           autoReadThread.Suspend();
        }

private void BtnStartAutoUpd_Click(object sender, EventArgs e)
        {
           autoReadThread.Resume();  
        }

但我正面临这个警告,

Thread.Suspend 已被弃用。请使用 System.Threading 中的其他类,例如 Monitor、Mutex、Event 和 Semaphore,以同步线程或保护资源。 http://go.microsoft.com/fwlink/?linkid=14202

我如何只运行单线程(而不是 GUI 线程),所以我如何在此处应用同步或监控。

更新代码:

 class ThreadClass
{

    // This delegate enables asynchronous calls for setting the text property on a richTextBox control.
    delegate void UpdateTextCallback(object text);

    // create thread that perform actual task
    public Thread autoReadThread = null;

    public ManualResetEvent _event = new ManualResetEvent(true);

    // a new reference to rich text box
    System.Windows.Forms.RichTextBox Textbox = null;

    private volatile bool _run;

    public bool Run
    {
        get { return _run; }
        set { _run = value; }
    }

    public ThreadClass(string name, System.Windows.Forms.RichTextBox r1)
    {
        Textbox = r1;
        Run = true;
        this.autoReadThread = new Thread(new ParameterizedThreadStart(UpdateText));
        this.autoReadThread.Start(name);
    }

    private void UpdateText(object fileName)
    {

        //while (true)
        //{
        //    _event.WaitOne();
            while (Run)
            {

                if (Textbox.InvokeRequired)
                {
                    UpdateTextCallback back = new UpdateTextCallback(UpdateText);
                    Textbox.BeginInvoke(back, new object[] { fileName });
                    Thread.Sleep(1000);
                }

                else
                {
                    string fileToUpdate = (string)fileName;
                    using (StreamReader readerStream = new StreamReader(fileToUpdate))
                    {
                        Textbox.Text = readerStream.ReadToEnd();
                    }
                    break;
                //}
            }
        }       
    }

}

}

run 是 bool 值,一个线程控制它(最初它是真的)

为了启动线程,我正在其他类中创建这个类实例(这个启动线程也是)

【问题讨论】:

  • 你更新不显示:a)你的线程是如何启动的,b)完整的线程方法。
  • InvokeRequired 始终为真。你的线程没有做任何有用的事情,一切都在 UI 线程上运行。

标签: c# .net multithreading monitoring deadlock


【解决方案1】:
 //true makes the thread start as "running", false makes it wait on _event.Set()
  ManualResetEvent _event = new ManualResetEvent(true); 
  Thread _thread = new Thread(ThreadFunc);

  public void ThreadFunc(object state)
  {
      while (true)
      {
          _event.Wait();

          //do operations here
      }
  }


  _thread.Start();

  // to suspend thread.
  _event.Reset();

  //to resume thread
  _event.Set();

注意所有操作都在线程“挂起”之前完成

你想要什么

private void ThreadFunc(object fileName)
{
    string fileToUpdate = (string)fileName;
    while (Run)
    {
        _event.WaitOne(); 

        string data;
        using (StreamReader readerStream = new StreamReader(fileToUpdate))
        {
            data = readerStream.ReadToEnd();
        }

        if (Textbox.InvokeRequired)
        {
            UpdateTextCallback back = new UpdateTextCallback(UpdateText);
            Textbox.BeginInvoke(back, new object[] { data });
        }

                Thread.Sleep(1000); 
    }       
}


private void UpdateText(string data)
{
    Textbox.Text = data;
}

【讨论】:

  • 不工作...执行在_event.Wait()处停止;之后我的操作没有被执行。
  • 你试过使用_event.Set()吗?我在ManualResetEvent 上将初始状态设置为false,这使它在继续之前等待设置
  • 我没有到达那里。 after_evenr.Wait() 我写了我的代码来执行,但是 wait stmnt 只挂在那里。 _event.reset 和 _evenr.Set 我在按钮事件中写的。
  • 我会亲自制作第一行ManualResetEvent _event = new ManualResetEvent(true);,因为默认行为应该是让线程运行。
  • @Damien_The_Unbeliever:正确。 @Pawan Kumar:在 ManualResetEvent 构造函数中更改为 true。检查更新的代码。
【解决方案2】:

不推荐使用 Suspend 和 Resume 的原因是因为无法保证线程将在执行的哪个时间点被挂起。这是一件坏事。该问题描述为here 以及解决方案。

解决方案应该涉及一个 WaitHandle(可能是 AutoResetEvent 或 ManualResetEvent),您可以使用它来向您的 autoReadThread 发出信号以停止/启动。

【讨论】:

    【解决方案3】:

    我会使用 Monitor 机制来实现暂停和恢复线程。 Monitor.Wait 将导致线程等待 Monitor.Pulse。

    private bool _pause = false;
    private object _threadLock = new object();
    
    private void RunThread()
    {
        while (true)
        {
            if (_pause)
            {
                lock (_threadLock)
                {
                    Monitor.Wait(_threadLock);
                }
            }
    
            // Do work
        }
    }
    
    private void PauseThread()
    {
        _pause = true;
    }
    
    private void ResumeThread()
    {
        _pause = false;
        lock (_threadLock)
        {
            Monitor.Pulse(_threadLock);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-05-30
      • 1970-01-01
      • 1970-01-01
      • 2017-03-12
      • 2012-03-01
      • 2019-04-04
      • 2018-12-12
      • 2014-09-18
      • 1970-01-01
      相关资源
      最近更新 更多