使用 Sql FILESTREAM 进行 Web 应用程序的学习和测试。客户端从网页上传一个大文件,这需要“X”时间,完全上传后显示 100% 完成。但是,非常大的文件也需要时间让 SqlFileStream 写入文件系统,所以我想分拆一个线程来完成该部分。我得到的代码似乎工作正常,但文件流文件中没有数据。
我将初始记录创建包装在它自己的事务范围中,并在线程中使用单独的事务范围。在线程例程中,我有适当的 PathName() 和 TransactionContext 但我假设我在使用线程时遗漏了一些东西。
我已经注释掉了正常工作的正常 SqlFileStream 调用。你能看出我在这里做的有什么问题吗?
Public Function StoreFileStream()
Dim json As New Dictionary(Of String, Object)
Dim parms As New FileStreamThreadParameters
If HttpContext.Current.Request.Files.Count > 0 Then
Dim file As HttpPostedFile = HttpContext.Current.Request.Files(0)
If "contentType" <> String.Empty Then
Dim fs As Stream = file.InputStream
Dim br As New BinaryReader(fs)
Dim noBytes As New Byte()
Try
Dim filePath As String = ""
Dim trxContext As Byte() = {}
Dim baseFileId As Integer
Using trxScope As New TransactionScope
Using dbConn As New SqlConnection(DigsConnStr)
Using dbCmd As New SqlCommand("ADD_FileStreamFile", dbConn)
dbConn.Open()
Using dbRdr As SqlDataReader = dbCmd.ExecuteReader(CommandBehavior.SingleRow)
dbRdr.Read()
If dbRdr.HasRows Then
filePath = dbRdr("Path")
trxContext = dbRdr("TrxContext")
baseFileId = dbRdr("BaseFileID")
End If
dbRdr.Close()
End Using
' Code below writes to file, but trying to offload this to a separate thread so user is not waiting
'Using dest As New SqlFileStream(filePath, trxContext, FileAccess.Write)
' fs.CopyTo(dest, 4096)
' dest.Close()
'End Using
End Using
dbConn.Close()
End Using
trxScope.Complete()
End Using ' transaction commits here, not in line above
parms.baseFileId = baseFileId
parms.fs = New MemoryStream
fs.CopyTo(parms.fs)
Dim fileUpdateThread As New Threading.Thread(Sub()
UpdateFileStreamThreaded(parms)
End Sub)
fileUpdateThread.Start()
json.Add("status", "success")
Catch ex As Exception
Elmah.ErrorSignal.FromCurrentContext().Raise(ex)
json.Add("status", "failure")
json.Add("msg", ex.Message)
json.Add("procedure", System.Reflection.MethodBase.GetCurrentMethod.Name)
End Try
Else
json.Add("status", "failure")
json.Add("msg", "Invalid file type")
json.Add("procedure", System.Reflection.MethodBase.GetCurrentMethod.Name)
End If
End If
Return json
End Function
Public Class FileStreamThreadParameters
Public Property baseFileId As Integer
Public fs As Stream
End Class
Private Sub UpdateFileStreamThreaded(parms As FileStreamThreadParameters)
Dim filePath As String = ""
Dim trxContext As Byte() = {}
Try
Using trxScope As New TransactionScope
Using dbConn As New SqlConnection(DigsConnStr)
Using dbCmd As New SqlCommand("SELECT FileBytes.PathName() 'Path', GET_FILESTREAM_TRANSACTION_CONTEXT() 'TrxContext' FROM FileStreamFile WHERE Id = " & parms.baseFileId, dbConn)
dbConn.Open()
Using dbRdr As SqlDataReader = dbCmd.ExecuteReader(CommandBehavior.SingleRow)
dbRdr.Read()
If dbRdr.HasRows Then
filePath = dbRdr("Path")
trxContext = dbRdr("TrxContext")
End If
dbRdr.Close()
Using dest As New SqlFileStream(filePath, trxContext, FileAccess.Write)
parms.fs.CopyTo(dest, 4096)
dest.Close()
End Using
End Using
End Using
dbConn.Close()
End Using
trxScope.Complete()
End Using
Catch ex As Exception
'Elmah.ErrorSignal.FromCurrentContext().Raise(ex)
End Try
End Sub