【问题标题】:VB.Net (or C#) 2008 Multi Threaded ImportVB.Net(或 C#)2008 多线程导入
【发布时间】:2008-09-18 18:57:10
【问题描述】:

我正在寻找构建一个多线程文本导入工具(通常是 CSV 到 SQL Server 2005)并希望在 VB.NET 中执行此操作,但我不反对 C#。我有 VS 2008 试用版,只是不知道从哪里开始。谁能指出我可以查看和使用 VS 2008 的非常简单多线程应用程序的源代码的方向?

谢谢!

【问题讨论】:

    标签: sql-server vb.net visual-studio multithreading import


    【解决方案1】:

    这是一篇很棒的文章:

    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
    

    【讨论】:

      【解决方案2】:

      引用的 DevX 文章来自 2001 年和 .Net Framework 1.1,但今天 .Net Framework 2.0 提供了BackgroundWorker 类。如果您的应用程序包含前台 UI 组件,这是推荐的线程类。

      来自MSDN Threads and Threading

      如果您需要运行后台线程 与用户界面交互, .NET 框架 2.0 版 提供一个 BackgroundWorker 组件 使用事件进行通信,与 跨线程编组到 用户界面线程。

      MSDN BackgroundWorker Class 中的这个示例显示了后台任务、进度 % 和取消选项。 (该示例比 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
      

      【讨论】:

      • 我已经在几个 VB.NET 项目中成功使用了 BackgroundWorker 组件。如果您的多线程需求相当简单,那就很难被击败。
      【解决方案3】:

      关于我发现的最好的线程文档是http://www.albahari.com/threading/

      如果可以的话,简单示例的问题在于它们通常过于简单。一旦您在后台演示中通过计数或排序,您通常需要更新 UI 或类似内容,并且有一些陷阱。同样,您很少需要在简单示例中处理资源争用问题,并且在资源不可用(例如 Db 连接)时让线程优雅地降级需要考虑。

      从概念上讲,您需要决定如何跨线程分配工作,以及您想要多少。管理线程会产生开销,并且某些机制使用共享线程池,这本身可能会受到资源争用的影响(例如,每当您运行一个仅显示空表单的程序时,您会在任务管理器下看到多少线程)。

      因此,对于您的情况,执行实际上传的线程需要在它们已完成、是否失败(以及失败原因)时发回信号。控制器需要能够处理这些问题并管理启动/停止进程等等。

      最后(几乎),假设多线程会提高性能并不总是成立。例如,如果您将文件分割成多个段,但它必须通过低速链路(例如 ADSL)传输,那么您会受到外力的限制,并且再多的线程技巧也无法解决这个问题。这同样适用于数据库更新、网络请求、任何涉及大量磁盘 i/o 的事情等等。

      尽管如此,我不是末日的预言家。这里的参考资料足以帮助您实现您想要的,但请注意,线程看起来很复杂的原因之一是因为它可以:)

      如果您想要比 BackgroundWorker/Threadpool 更多的控制,但又不想自己做所有事情,那么至少有两个非常好的免费线程库(Wintellect 和 PowerThreading)

      干杯

      西蒙

      【讨论】:

      • 感谢西蒙的回复。那一篇优秀的文章/资源!!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多