2015-02-18 2 views
1

У меня есть приложение, которое получает данные из базы данных, обрабатывает его, а затем отправляет его на определенный IP-адрес. Я хочу, чтобы он использовал BackgroundWorker, чтобы избежать остановки графического интерфейса.Правильно ли вызывать функцию из BackGroundWorker?

Код в обработчике событий BackgroundWorker слишком длинный и сложный, поэтому я думаю о том, чтобы разделить этот код на многие функции, чтобы лучше организовать код.

В порядке? Могу ли я написать эти функции в том же классе Form1 и вызвать их из BackgroundWorker? Нужно ли мне создавать новый класс?

ответ

4

Да, это совершенно приемлемо, если не предпочтительнее. Вопрос не в том, вызываете ли вы другие методы из события BackgroundWorker. Скорее, вопрос в том, что эти функции фактически do. Если они изменяют элементы пользовательского интерфейса, это неприемлемо, независимо от того, сделано это или обработчик события или в отдельной функции. Аналогичным образом, если они используют небезопасные объекты, которые совместно используются с потоком пользовательского интерфейса без SyncLock, то это тоже проблема в любом месте. Итак, да, если выполняемая работа является потокобезопасной, то это вообще не имеет значения, если это делается в обработчике событий, отдельном методе или даже в другом классе или библиотеке.

Например, если ваш метод должен обновить RichTextBox управление из фонового потока, вы могли бы сделать что-то вроде этого:

Private Sub BackgroundWorker1_DoWork(sender As Object, e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork 
    GenerateReport() 
End Sub 

Private Sub GenerateReport() 
    Dim rtf As String = ' ... 
    Me.Invoke(Sub() RichTextBox1.Rtf = rtf) 
End Sub 
+0

Хорошо, спасибо за ваш пример; Теперь я понимаю. Вы используете выражение лямбда на последней строке, правильно? –

+0

Да. Это необязательно. Вы можете использовать делегат для обычного метода, но, как видите, лямбда-выражения особенно полезны для такого рода вещей. –

+0

Итак, могу ли я напрямую вызвать делегата или заменить «RichTextBox1.Rtf = rtf» на «WriteRTBLog (rtf, Color)» в выражении лямбда? –

1

BackgroundWorker может, безусловно, вызывать функции. Как и в коде в методе DoWork BackgroundWorker, вам нужно убедиться, что код в функции не пытается обновить те же объекты, которые обновляется в основном потоке в основном потоке. Например, вам нужно либо не обновлять элементы управления пользовательским интерфейсом, либо использовать поточно-безопасный способ сделать это.

+0

В настоящее время у меня есть RichTextBox, что я обновляю через делегат. Должен ли я не называть этого делегата? Я использую это как LOG –

+1

Каждый раз, когда вам нужно прикоснуться к элементу управления пользовательским интерфейсом, например «RichTextBox» из фонового потока, вам нужно вызвать метод «Invoke» или «BeginInvoke» формы или элемента управления, предоставив ему делегат к методу, который обновляет элемент управления. –

+0

Я не понимаю, что вы мне объясняете. Вы пытаетесь сказать мне, что вызов делегата непосредственно из BackGroundWorker не подходит, и я должен выполнить Invoke для Form1, а затем вызвать делегата? Мне нужно провести исследование в Google. Должен ли я искать «Invoke» напрямую? Я не знаю, что это даст мне результаты, которые мне нужно понять. –

Смежные вопросы