0

iTextSharp を使用して (これは iTextSharp に関連しているわけではありません)、次のようなコードを使用して PDF バイトを生成します。

Function GetFileBytes() as Byte()
Dim result() As Byte
    Using ms As New MemoryStream

        Dim reader As New PdfReader(pdfForm)
        Dim writer As New PdfStamper(reader, ms)

        Dim fields As AcroFields = writer.AcroFields

        fields.SetField("Customer Name", custInfo.FirstName + " " + custInfo.LastName)

        result = ms.GetBuffer
    End Using
End Function

代わりにこれを非同期タスクにして、代わりに Task(Of Byte()) を返したいのですが、メモリストリームを非同期モードで書き込む方法と、Task(Of Byte()) を返す方法を理解するのに問題があります。 ) 過程の中で。ヒント、提案はありますか?ありがとう!

EDIT 1 タスクを使用してこのコードを使用する必要性を明確にしたかったのは、これまでのところ、「なぜこのようにするのか」と「代わりにこれを行うだけではなく、丁寧に「ありがとう、でも私はこのようにしたい」と言ってください:)

これが私のシナリオです。いくつかのページでデータを収集し、レビュー画面を表示し、ユーザーがそのデータを含む PDF を表示できるようにする Web サイトを想像してみてください。レビュー画面では、1 MB の PDF ファイルを生成し、それを BLOB ストレージにアップロードして、ユーザーがダウンロードすることを選択したときに利用できるようにする必要があります。

ユーザーが「PDF の表示」ボタンを選択したときではなく、レビュー画面を確認しているときに PDF を生成してアップロードしたいと考えています。そのコードは私の例を使用して実行されます。そのため、Byte() 型の Task を作成する方法に興味があります。どんな助けでも大歓迎です、ありがとう!

4

4 に答える 4

0

編集への対応: このシナリオは理にかなっています。Task.Runすべてを呼び出しにラップします。スレッドセーフであることを確認してください (たとえば、タスクで HttpContext を使用しないでください)。バグの可能性があるため、エラーもログに記録します。

ただし、ASP.NET では、バックグラウンド作業はいつでも中止できることに注意してください (たとえば、ワーカー プロセスのリサイクル時)。バックグラウンドでの作業が突然消えることを許容する必要があります。あなたの場合、ユーザーがアクセスしようとするとPDFが見つからない可能性があります。また、ユーザーがダウンロードしようとしたときにまだ生成されている場合はどうなりますか。それらの問題を解決しなければなりません。

于 2013-10-04T16:34:08.637 に答える
0

本当に非同期にしたい場合、より簡単な方法は、クラスにプライベート スレッドを作成することです。そのスレッドは page_init でプロセスを開始し、Page_LoadComplete でスレッドは thread.join() を使用して待機し、関数を取得します。ただし、前述のように、相対速度の向上は最小限です。スレッド (またはタスク) は非常に高価であることを考慮してください。

オプション 2
は、pdf ファイル データを返す汎用ハンドラーへの ajax 要求を作成します。この方法では、スレッドが関与せず、ユーザー エクスペリエンスが向上します。

<%@ WebHandler Language="VB" Class="GetFile" %>

Imports System
Imports System.Web
Imports System.IO

Public Class GetFile : Implements IHttpHandler


    Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest        
        context.Response.Clear()        
            If File.Exists(filePath & docName) Then
                context.Response.AddHeader("content-disposition", "attachment; filename=" & HttpContext.Current.Server.UrlEncode(docName))
                context.Response.ContentType = "text/pdf"
                context.Response.WriteFile(filelocation & docName) 'in your case this writes the bites of the generated file, so instead of the path just pass in the data
            End If 
        context.Response.Flush()
        context.Response.End()
    End Sub

    Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
        Get
            Return False
        End Get
    End Property

End Class
于 2013-10-04T16:44:32.407 に答える
-1

(以下のコードは使用しないでください。理由については、「回答」の最後を参照してください)。

助けてくれてありがとう。結局、私はこれに間違って近づいていました。必要なのは、Task(Of Byte()) を返す Async ラッパー関数を作成することだけでした。

したがって、私の最初のコードが次の場合:

Function GetFileBytes() as Byte()
    Dim result() As Byte

      Using ms As New MemoryStream

        Dim reader As New PdfReader(pdfForm)
        Dim writer As New PdfStamper(reader, ms)

        Dim fields As AcroFields = writer.AcroFields

        fields.SetField("Customer Name", custInfo.FirstName + " " + custInfo.LastName)

        result = ms.GetBuffer
    End Using
End Function

ここで、上記と同じ GetFileBytes メソッドを呼び出す Task(Of Byte()) を返す GetFileBytesAsync という新しいメソッドを作成しました。このメソッドは、次のように Task.Factory.StartNew を使用して呼び出されます。

Public Shared Async Function GetFileBytesAsync() As Task(Of Byte())
        Dim t As Task(Of Byte()) = Task.Factory.StartNew(Function()
                                                             Return GetFileBytes()
                                                         End Function)

        Return Await t

    End Function

呼び出し関数では、タスク オブジェクトの Result プロパティを使用してバイト配列にアクセスします。チッ!

編集:OK、Stephen Clearyが適切に指摘したように、私はこれをすべて間違ってやっています.上記のコードは推奨されておらず、非同期的に何もしていません..実際のところ、新しいスレッドを作成していくつかのブロッキングコードを作成しています. ごめん...

この TechEd トークに出くわしました: http://channel9.msdn.com/Events/TechEd/NorthAmerica/2013/DEV-B337 - 非同期を使用して ASP.NET Web アプリケーションを構築する方法です。54 分の時点で、ASP.NET Web サーバーで "バックグラウンド スレッド" を使用しようとするのは間違っていることを実際に示しています。 Web リクエストに応答するために使用されます。

于 2013-10-08T20:20:01.140 に答える