Какая из этих функций наиболее эффективна?
При использовании потока используется "invoke", чтобы избежать "Cross Thread" (1)
но иногда "объект таймера" используется, чтобы избежать "CrossThread" (2)
как это (например)
public partial class Form1 : Form
{
private bool bCheckState = false;
public Form1()
{
InitializeComponent();
}
//Button Click
private void btnWork_Click(object sender, EventArgs e)
{
Thread m_Thread = new Thread(new ThreadStart(Work));
m_Thread.Start();
}
private void Work()
{
bCheckState = true;
// not use invoke
}
private void timer_Tick(object sender, EventArgs e)
{
if (bCheckState)
{
//tbxDisplay is winform's textBox control - printing data
tbxDisplay.Text = bCheckState.ToString();
bCheckState = false;
}
}
}
какой из них более эффективен? "между (1) и (2)"
Может ли это быть проблемой, если мы разбрасываем данные, обработанные в "потоке", после проверки их в "событии таймера", без использования "invoke" или других методов? (Мы слышали, что во избежание "перекрестного потока" при печати данных, обработанных в "потоке", разбрасывание данных в "событии таймера" с дополнительным "объектом таймера" использовалось довольно часто, поскольку это ни полезно, ни вредно).
2 ответа
Как предложил Бен Фойгт, BackgroundWorker
это, вероятно, то, что вы должны использовать здесь, если у вас нет веских причин хотеть использовать что-то еще.
"Эффективный" - довольно смутное средство сравнения. Не совсем понятно, что вы ищете в двух вариантах, которые вы рассматриваете.
BackgroundWorker
Они просты и понятны, и они избегают использования таймеров.
Invoke
более эффективен, чем таймер, в том смысле, что задержка между bCheckState и истечением текста будет меньше. Он также будет менее ресурсоемким, поскольку у вас не будет опроса таймера через заданный интервал.
Timer
более эффективен в том смысле, что поток не должен останавливаться при вызове для обновления текста, но он немного неэффективен, потому что он будет тратить впустую процессорное время, проверяя, изменился ли логический тип, и также может быть задержка до длины интервала таймера до изменения формы.
Как еще одна альтернатива, BeginInvoke
может использоваться для обновления формы без использования таймера и без необходимости в потоке, ожидающем завершения вызова. Тем не менее, если возникнет исключение, ваш поток может не узнать, если вы затем не вызовите EndInvoke
, что также остановит выполнение потока до завершения вызова.
Все они имеют свои преимущества и недостатки, и вы не можете назвать какой-то конкретный более "эффективным" в целом.
Просто используйте BackgroundWorker
экземпляр и обрабатывать ReportProgress
и / или RunWorkerCompleted
события, которые уже есть в нужной ветке.