#c# #.net-2.0
#c# #.net-2.0
Вопрос:
Я поиграл с методами безопасного вызова метода потокобезопасным способом в .net 2.0.
Мой treeview заполняется из вызова базы данных в отдельном потоке;
Ниже приведена моя попытка использовать мой метод InvokeFunction (показан ниже) … это работает, но я надеялся, что есть более приятный способ написать это … есть мысли по этому поводу?
InvokeFunction(delegate() { TreeView1.Nodes.Clear(); });
delegate void FunctionDelegate();
private delegate void ThreadSafeProcess(FunctionDelegate func);
private void InvokeFunction(FunctionDelegate func)
{
if (this.InvokeRequired)
{
ThreadSafeProcess d = new ThreadSafeProcess(InvokeFunction);
this.Invoke(d, new object[] { func });
}
else
{
func();
}
}
Комментарии:
1. Невозможно ответить на этот вопрос, если вы не расскажете больше о том, что делает ваша функция. Доступно много-много разных механизмов синхронизации, которые решают разные проблемы. Какой из них подходит, зависит от решаемой проблемы. В чем ваша проблема?
2. Дэвид, как ты можешь видеть, функция вызывает метод treeview clear nodes() для очистки узлов. Я просто поиграл с идеей создания чего-то более общего, чем явный вызов метода forms.control.
Ответ №1:
BackgroundWorker
это более чистое решение в .NET 2.0. Это создаст для вас поток и позаботится о синхронизации.
Вы добавляете BackgroundWorker
компонент в свою форму в режиме разработки. Вы подписываетесь на DoWork
событие. Метод, подписанный на это, будет выполняться в фоновом потоке при вызове backgroundWorker.RunWorkerAsync()
в вашем потоке пользовательского интерфейса.
Когда вам нужно взаимодействовать с потоком пользовательского интерфейса из вашего фонового потока, вы вызываете backgroundWorker.ReportProgress
. Это вызовет ProgressChanged
событие. ProgressChanged
событие всегда выполняется в потоке пользовательского интерфейса. Вы можете использовать userState
параметр backgroundWorker.ReportProgress
для передачи любых данных в поток пользовательского интерфейса. Например, в вашем случае данные, необходимые для добавления новых TreeView
узлов. Вы фактически добавите новые узлы внутри ProgressChanged
обработчика событий.
Вот ссылка на MSDN:http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx .
Имейте в виду, что вам не обязательно использовать percentProgress
параметр метода ReportProgress
method. Хотя это удобно, когда у вас есть индикатор выполнения, отражающий ход фоновой работы.
Комментарии:
1. Я предполагаю, что это WinForms. Брэд сказал: «Мой treeview заполняется из вызова базы данных в отдельном потоке». К TreeView не должен быть доступ из любого другого потока, кроме потока пользовательского интерфейса. Итак, здесь требуется синхронизация потоков пользовательского интерфейса.
Ответ №2:
Вам не нужно беспокоиться о безопасности потоков, если вы не разделяете какое-либо состояние. Функции всегда получают свои параметры в стеке, а стек является локальным для каждого потока. Итак, функции — это не ваша проблема. Вместо этого сосредоточьтесь на состоянии. Объекты «treeView1» — это кандидат, о котором стоит беспокоиться.