VB.Net (или C#) 2008 Многопоточный Импорт
Я хочу создать средство многопоточного импорта текста (обычно CSV в SQL Server 2005) и хотел бы сделать это в VB.NET, но я не против C#. У меня есть пробная версия VS 2008, и я просто не знаю, с чего начать. Может кто-нибудь указать мне, где я могу посмотреть и поиграть с источником ОЧЕНЬ простого многопоточного приложения для VS 2008?
Спасибо!
3 ответа
Ссылочная статья DevX относится к 2001 году и.Net Framework 1.1, но сегодня.Net Framework 2.0 предоставляет класс BackgroundWorker. Это рекомендуемый класс потоков, если ваше приложение включает компонент пользовательского интерфейса переднего плана.
Если вам нужно запустить фоновые потоки, которые взаимодействуют с пользовательским интерфейсом,.NET Framework версии 2.0 предоставляет компонент BackgroundWorker, который взаимодействует с использованием событий с межпотоковым маршалингом в поток пользовательского интерфейса.
В этом примере из класса MSDN BackgroundWorker показаны фоновая задача, процент выполнения и параметр отмены. (Пример длиннее образца DevX, но имеет гораздо больше функциональности.)
Imports System.ComponentModel
Partial Public Class Page
Inherits UserControl
Private bw As BackgroundWorker = New BackgroundWorker
Public Sub New()
InitializeComponent()
bw.WorkerReportsProgress = True
bw.WorkerSupportsCancellation = True
AddHandler bw.DoWork, AddressOf bw_DoWork
AddHandler bw.ProgressChanged, AddressOf bw_ProgressChanged
AddHandler bw.RunWorkerCompleted, AddressOf bw_RunWorkerCompleted
End Sub
Private Sub buttonStart_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
If Not bw.IsBusy = True Then
bw.RunWorkerAsync()
End If
End Sub
Private Sub buttonCancel_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
If bw.WorkerSupportsCancellation = True Then
bw.CancelAsync()
End If
End Sub
Private Sub bw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
For i = 1 To 10
If bw.CancellationPending = True Then
e.Cancel = True
Exit For
Else
' Perform a time consuming operation and report progress.
System.Threading.Thread.Sleep(500)
bw.ReportProgress(i * 10)
End If
Next
End Sub
Private Sub bw_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
If e.Cancelled = True Then
Me.tbProgress.Text = "Canceled!"
ElseIf e.Error IsNot Nothing Then
Me.tbProgress.Text = "Error: " & e.Error.Message
Else
Me.tbProgress.Text = "Done!"
End If
End Sub
Private Sub bw_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)
Me.tbProgress.Text = e.ProgressPercentage.ToString() & "%"
End Sub
End Class
Это отличная статья:
http://www.devx.com/DevX/10MinuteSolution/20365
Особенно:
Dim t As Thread
t = New Thread(AddressOf Me.BackgroundProcess)
t.Start()
Private Sub BackgroundProcess()
Dim i As Integer = 1
Do While True
ListBox1.Items.Add("Iterations: " + i)
i += 1
Thread.CurrentThread.Sleep(2000)
Loop
End Sub
Самым лучшим документом о потоках, который я когда-либо нашел, был этот http://www.albahari.com/threading/
Если позволите, проблема простых примеров в том, что они часто слишком просты. Как только вы закончите подсчет или сортировку в фоновых демонстрациях, вам, как правило, нужно обновить пользовательский интерфейс или аналогичный, и есть некоторые ошибки. Точно так же вам редко приходится сталкиваться с конфликтом ресурсов в простых примерах, и для того, чтобы потоки изящно деградируют, когда ресурс недоступен (например, соединение Db), необходимо подумать.
Концептуально вам нужно решить, как вы собираетесь распределять свою работу по потокам и сколько вы хотите. С управлением потоками связаны накладные расходы, и некоторые механизмы используют общий пул потоков, который может быть подвержен самому конфликту ресурсов (например, каждый раз, когда вы запускаете программу, которая просто отображает пустую форму, сколько потоков вы видите в диспетчере задач).
Так что для вашего случая вы, потоки, выполняющие фактическую загрузку, должны сообщить о том, что они завершились, если они потерпели неудачу (и какова была ошибка). Контроллер должен иметь возможность справляться с ними и управлять процессами запуска / остановки и так далее.
Наконец (почти), предположение, что создание многопоточности увеличит производительность, не всегда верно. Например, если вы разбили файл на сегменты, но он должен проходить по низкоскоростному каналу (скажем, ADSL), вы ограничены внешними силами, и никакие хитрости с многопоточностью не помогут. То же самое можно применить к обновлениям базы данных, веб-запросам, всему, что связано с большим количеством дисковых операций ввода-вывода и так далее.
Несмотря на все это, я не пророк гибели. Приведенные здесь ссылки более чем адекватны, чтобы помочь вам достичь того, чего вы хотите, но помните, что одна из причин, по которым многопоточность кажется сложной, заключается в том, что она может быть:)
Если вам нужен больший контроль, чем у BackgroundWorker/Threadpool, но вы не хотите делать все сами, есть по крайней мере две очень хорошие библиотеки потоков для халявы, которые работают вокруг (Wintellect & PowerThreading)
ура
Саймон