1

Web サービスを介してデータを送信することにより、大きな SQL テーブルをデータベースから別のデータベースにコピーする必要があるコンソール アプリケーションを作成しています。テーブルは非常に大きくなる可能性があり、完全にメモリに格納することはできません (そしてすべきではありません) ため、DataReader を使用してデータを順番に読み取り、それを Web サービスにストリーミングしたいと考えていました。

これを行うために、Web サービスを次のように宣言します。

<OperationContract()>
<WebInvoke(UriTemplate:="{Id}/SendData", method:="PUT", BodyStyle:=WebMessageBodyStyle.WrappedRequest)>
Sub UploadData(ByVal Id As String, ByVal DataStream As Stream)

私のコンソール アプリケーションでは、次のようにリクエストを作成しています。

    Dim tRequest As HttpWebRequest = HttpWebRequest.Create(URL_WEBSERVICES & "DataLoad/" & _Id & "/SendData")
    tRequest.SendChunked = True
    tRequest.Method = "PUT"
    tRequest.ContentType = "application/octet-stream"

次に、リクエスト ストリームを開き、次のようにデータを書き込みます。

While tSqlReader.Read
    ' Check if a new chunk of data must be created
    If tRows Is Nothing Then
        tRows = New List(Of Object)
    End If
    ' Fill chunk with data
    tRowValues = New Object(tSqlReader.FieldCount - 1) {}
    tSqlReader.GetValues(tRowValues)
    tRows.Add(tRowValues)
    ' Check if chunk is full and must be sent
    If tRows.Count = CHUNK_ROWS_COUNT Then
        ' Write data to the request stream
        tDataChunk = SerializeToByteArray(tRows)
        tStream.Write(tDataChunk, 0, tDataChunk.Length)
        tRows = Nothing
        tDataChunk = Nothing
    End If
End While
' Write final data to the request stream
If tRows IsNot Nothing Then
    tDataChunk = SerializeToByteArray(tRows)
    tStream.Write(tDataChunk, 0, tDataChunk.Length)
End If

次に、リクエスト ストリームを閉じて、tRequest.GetResponse() を呼び出します。

SerializeToByArray は次の関数です。

Private Function SerializeToByteArray(ByVal pObject As Object) As Byte()
    If pObject Is Nothing Then Return Nothing
    Dim tBinaryFormatter As New Runtime.Serialization.Formatters.Binary.BinaryFormatter
    Dim tMemoryStream As New MemoryStream()
    tBinaryFormatter.Serialize(tMemoryStream, pObject)
    Return tMemoryStream.ToArray
End Function

私の問題は、Web サービスがデータの最初のチャンクしか受信しないことです。たとえば、CHUNK_ROWS_COUNT = 5 の場合、5 行のデータしか受信しません。(これは、HttpWebRequest が作成するチャンクのサイズではないことを認識しています)。

私の唯一の推測は、ストリームを介していくつかのシリアル化されたデータ パックを送信し、それぞれがいくつかのシリアル化ヘッダーによってカプセル化されているため、Web サービスの逆シリアル化プロセスは最初のもののみを見つけてカプセル化解除することですが、それは単なるアイデアであり、私は別の方法で行う方法がわかりません。コンテンツ全体がメモリに収まらないため、コンテンツ全体をシリアル化してチャンクで送信することはできません。

何かアドバイス?

事前にどうもありがとう

4

1 に答える 1

0

手動の HttpWebRequest を使用して WCF でこれを実行できるかどうかはわかりません。WCF はそれ自体でチャンクを処理し、車輪を再発明しません。

いくつかの素晴らしい記事:

wcf config でリーダー クォータを変更することを忘れないでください

于 2012-09-17T11:11:30.743 に答える