我正在寻求构建多线程文本导入工具(通常将CSV导入SQL Server 2005),并希望在VB.NET中做到这一点,但我并不反对C#。 我有VS 2008试用版,只是不知道从哪里开始。 谁能指出我的方向,让我可以查看和使用VS 2008的一个非常简单的多线程应用程序的源代码?
谢谢!
这是一篇很棒的文章:
http://www.devx.com/DevX/10MinuteSolution/20365
特别是:
1 2 3 4 5 6 7 8 9 10 11 12
| 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 |
引用的DevX文章来自2001和.Net Framework 1.1,但今天.Net Framework 2.0提供了BackgroundWorker类。如果您的应用程序包括前台UI组件,则这是推荐的线程类。
从MSDN线程和线程:
If you need to run background threads
that interact with the user interface,
the .NET Framework version 2.0
provides a BackgroundWorker component
that communicates using events, with
cross-thread marshaling to the
user-interface thread.
MSDN BackgroundWorker类中的此示例显示了后台任务,进度%和cancel选项。 (该示例比DevX示例更长,但具有更多功能。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| 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.albahari.com/threading/
如果可以的话,简单示例的问题在于它们通常太简单了。一旦超过计数或在后台演示中进行排序,通常就需要更新UI或类似内容,并且有些陷阱。同样,您几乎不必在简单的示例中处理资源争用,并且在资源不可用(例如Db连接)时,线程会优雅地降级。
从概念上讲,您需要确定如何将工作分配到各个线程中以及需要多少个。与管理线程相关的开销很大,某些机制使用的共享线程池本身可能会受到资源争用的影响(例如,每当您运行一个仅显示空表格的程序时,在任务管理器下就会看到多少个线程)。
因此,对于您的情况,执行实际上载的线程需要发回信号,告知它们是否已完成,是否失败(以及失败的原因)。控制器需要能够处理这些问题并管理启动/停止过程等。
最后(几乎),假设创建多线程可以提高性能并不总是成立。例如,如果您将文件切成段,但必须通过低速链接传输(ADSL这样说),那么您将受到外力的束缚,并且没有任何解决方法。这同样适用于数据库更新,Web请求,任何涉及大量磁盘I / O的事情等等。
尽管如此,我不是厄运的先知。这里的参考文献足以帮助您实现所需的目标,但是请注意,线程看起来很复杂的原因之一是因为它可能是:)
如果您想要比BackgroundWorker / Threadpool更好的控制权,但又不想自己做任何事情,那么至少有两个非常不错的免费赠品线程库在附近(Wintellect和PowerThreading)
干杯
西蒙