С# Threading.Suspend in Obsolete, поток устарел?
В моем приложении я выполняю чтение своего файла другим потоком (другим, который является потоком GUI). Есть две кнопки, которые приостанавливают и возобновляют Thread соответственно.
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)
и начать поток Я создаю этот экземпляр класса (этот начальный поток также) в другом классе
Ответы
Ответ 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;
}
Ответ 2
Причина, по которой Suspend и Resume устарели, заключается в том, что нет никаких гарантий, на каком этапе выполнения поток будет приостановлен. Это плохо. Проблема описана здесь, а также решение.
Решение должно включать 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);
}
}