0

我正在尝试从 .NET 3.5 上用 VB.NET 编写的 ASP 页面生成一个新线程。

该页面允许用户上传文件,然后将文件处理到数据库中。由于处理可能需要一段时间,我想上传它们,将处理生成到一个新线程上,然后当它完成时通过系统中的数据库驱动通知模块向用户发送通知。

我尝试了几个在网上找到的不同示例,但它们似乎不起作用。没有抛出错误,但它似乎也从未在新线程上实际启动处理代码。

这是我在网页中的提交代码:

Protected Sub btnSubmit_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSubmit.Click
    Try
        If Not (file1.HasFile Or file2.HasFile Or file3.HasFile Or file4.HasFile Or file5.HasFile) Then
            AddErrorMessage("Please specify at least one file.")
        Else
            Dim l = New List(Of InventoryUploads.File)

            If file1.HasFile Then l.Add(New InventoryUploads.File With {.Name = file1.FileName, .Content = file1.FileContent})
            If file2.HasFile Then l.Add(New InventoryUploads.File With {.Name = file2.FileName, .Content = file2.FileContent})
            If file3.HasFile Then l.Add(New InventoryUploads.File With {.Name = file3.FileName, .Content = file3.FileContent})
            If file4.HasFile Then l.Add(New InventoryUploads.File With {.Name = file4.FileName, .Content = file4.FileContent})
            If file5.HasFile Then l.Add(New InventoryUploads.File With {.Name = file5.FileName, .Content = file5.FileContent})

            InventoryUploads.ProcessFiles(l, Session.UserIdent, chkRcvOverwrite.Checked)

            NewRow("Your files have been queued and are being processed. You will be sent a notification when they are completed.")
        End If
    Catch ex As Exception
        LogEx(ex)
        NewRow("There was an error queueing your files." & BR & ex.Message)
    End Try
End Sub

从 UI 的角度来看,这一切正常,页面发布文件,并向用户显示有关“您的文件已排队”的消息。

调用toInventoryUploads.ProcessFiles是线程代码前面的一个封装函数,全部包含在InventoryUploads模块中(如下):

Imports System.Threading
Imports System.Threading.Tasks

Public Module InventoryUploads
  Public Structure File
    Private pName As String
    Private pContent As IO.Stream
    Private pProcessed As Boolean

    Public Property Name As String
        Get
            Return pName
        End Get
        Set(value As String)
            pName = value
        End Set
    End Property

    Public Property Content As IO.Stream
        Get
            Return pContent
        End Get
        Set(value As IO.Stream)
            pContent = value
        End Set
    End Property

    Public Property Processed As Boolean 
        Get
            Return pProcessed
        End Get
        Set(value As Boolean)
            pProcessed = value
        End Set
    End Property
  End Structure

  Public Sub ProcessFiles(files As List(Of File), userident As String, receivingsOverwrite As Boolean)
    Try
        Dim params = Array.CreateInstance(GetType(Object), 3)
        params(0) = files
        params(1) = userident
        params(2) = receivingsOverwrite

        '// Threading Method 1
        Dim pts = New ParameterizedThreadStart(AddressOf ThreadedProcessFiles)
        Dim thd = New Thread(pts)
        thd.IsBackground = True
        thd.Start(params)

        '// Threading Method 2
        'ThreadPool.QueueUserWorkItem(AddressOf ThreadedProcessFiles, params)

        '// Threading Method 3
        Dim f As Func(Of Integer) = Function() ThreadedProcessFiles(params)
        Task.Factory.StartNew(f)
    Catch ex As Exception
        IO.File.WriteAllText("C:\idwherenet.log", ex.Message)
        Throw
    End Try
  End Sub

''' <summary>
''' 
''' </summary>
''' <param name="params">exepcts params to contain 3 objects, 
''' 1) type List(Of File), 
''' 2) string userident to notify on finish
''' 3) boolean whether receivings should overwrite</param>
''' <remarks></remarks>
  Private Function ThreadedProcessFiles(params() As Object) As Boolean
    IO.File.WriteAllText("C:\mylog.log", "hello ThreadedProcessFiles?")
    'Log("threadedprocessfiles: got here")

    Dim files As List(Of File), uident As String = "", rcvovr As Boolean
    Try
        files = params(0)
        uident = CStr(params(1))
        rcvovr = CBool(params(2))

        If files.Count = 0 Then
            SendNotification(NotificationTypes.SYS, uident, "No files provided for inventory upload; nothing processed.")
            Exit Sub
        End If

        For Each f In files
            f.Processed = False
            If f.Content.Length = 0 Then Continue For

            '// process the file here....

            f.Processed = True
        Next

        SendNotification(NotificationTypes.SYS, uident, "Inventory upload processing completed.")
        Return True
    Catch ex As Exception
        'LogEx(ex)
        'Log(ex.Message, ex.ToString)
        If Not uident.IsEmpty Then SendNotification(NotificationTypes.SYS, uident, "Inventory upload processing encountered an error. " & ex.Message, ex.ToString)
        Return False
    End Try
  End Sub
End Module

ProcessFilessub 中,您可以看到我尝试生成线程的三种不同方法,包括Task Parallel Library的 NuGet backport ... 都不起作用。我已经确认是进入子程序ProcessFiles,并且生成线程的代码没有抛出任何错误......它只是从未真正调用过该ThreadedProcessFiles函数。

有任何想法吗?

更新:哦,实际上,NuGet 包似乎正在工作,终于!它只是不写出文件(我猜是上下文/安全/模拟权限)。现在我终于可以继续前进了!

4

1 回答 1

3

如果您使用的是 .NET 4 或 4.5,Task Parallel Library 让这种事情变得超级简单:

Task.Factory.StartNew(Function() ThreadedProcessFiles(params));

(我认为这是 VB 的正确语法)

如果您走这条路线,我会将参数更改为仅分别发送三个参数。

于 2013-05-17T17:44:01.750 回答