C # Threading.Suspend в устаревшем, поток устарел? - PullRequest
10 голосов
/ 22 декабря 2010

В моем приложении я выполняю чтение моего файла другим потоком (кроме этого потока 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, поток контролирует его (изначально оно имеет значение true)

, и для запуска потока я создаю этот экземпляр класса (этот стартовый поток также) вкласс

Ответы [ 3 ]

9 голосов
/ 22 декабря 2010
 //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;
}
5 голосов
/ 22 декабря 2010

Причина, по которой Suspend и Resume устарели, заключается в том, что нет никаких гарантий, на каком этапе выполнения поток будет приостановлен.Это плохо.Проблема описана здесь , а также решение.

Решение должно включать WaitHandle (может быть AutoResetEvent или ManualResetEvent), который вы можете использовать, чтобы подать сигнал autoReadThread на остановку / запуск.

3 голосов
/ 22 декабря 2010

Я бы использовал механизм 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);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...