2016-08-03 8 views
0

BuildReports()を非同期にする必要があります。この関数は、作成する必要があるレポートの数に応じて完了までに数分かかることがあります。これはbtnClearAll_Click()によって呼び出され、「Async」と「Await」も追加されています。 BuildReports()に 'Async'を追加し、ループの前にIf-Then-Else 'ステートメントでの使用を含む' Await 'の数多くのプレースメントを試しました。また、reportComponent.CreatePDF()(SQL Selectクエリ)で作成されたデータテーブル(dt)に対して「Awaitable」を試しました。 ClearAll()は同期です。ループ内のタスクベースの非同期パターン

私はここでいくつかの助けが必要です、私はこれに関する多くの記事を読んだが、私は何かが欠けている。どんな指導も高く評価されます。

Private Async Sub btnClearAll_Click(sender As Object, e As System.EventArgs) Handles btnClearAll.Click 

    Await BuildReports() 

    ClearAll() 

End Sub 

Private Async Function BuildReports() As Task 

    Try 
     Dim reportComponent As New ReportComponent(CStr(Session("UserConnectionString"))) 
     Dim dt As New DataTable 

     dt = reportComponent.CreatePDF() 

     If dt IsNot Nothing Then 
      Dim ScheduleDto As New ScheduleDto() 
      Dim scheduleDtoList As New List(Of ScheduleDto)() 
      Dim report1 As Telerik.Reporting.Report = Nothing 

      For Each row As DataRow In dt.Rows 
       For i As Integer = 0 To dt.Rows.Count - 1 
        If row IsNot Nothing Then 
         ScheduleDto.Encounter_code = dt.Rows.Item(i).Item("Encounter_code").ToString 
         ScheduleDto.CaseNumber = dt.Rows.Item(i).Item("CaseNumber").ToString 
         ScheduleDto.Case_Name = dt.Rows.Item(i).Item("Case_Name").ToString 
         ScheduleDto.DOS = dt.Rows.Item(i).Item("DOS").ToString 
         ScheduleDto.Provider = dt.Rows.Item(i).Item("Provider").ToString 
         ScheduleDto.Discipline = dt.Rows.Item(i).Item("Discipline").ToString 
         ScheduleDto.Episode = dt.Rows.Item(i).Item("Episode").ToString 
         ScheduleDto.ReportType = dt.Rows.Item(i).Item("ReportType").ToString 
         ScheduleDto.DocumentName = dt.Rows.Item(i).Item("Document_Name").ToString 
         ScheduleDto.ItemType = dt.Rows.Item(i).Item("ItemType").ToString 

         scheduleDtoList.Add(ScheduleDto) 
         report1 = reportComponent.GetReport(ScheduleDto, ScheduleDto.ReportType, CStr(Session("UserConnectionString"))) 
         If (report1 IsNot Nothing) Then 
          Dim pdfPath As String = "" 
          Dim DownloadReport As New DownloadReports() 
         DownloadReport.DownloadReport(report1, ScheduleDto, ScheduleDto.DocumentName, ScheduleDto.ReportType, pdfPath) 
         reportComponent.FinalizeNow(ScheduleDto.Encounter_code) 

         End If 
        End If 
       Next 
      Next 

     Else : Return 
     End If 

    Catch ex As SqlException 
     Throw New Exception(ex.Message & " : Build_Reports") 
    Finally 
    End Try 


End Function 

答えて

0

BuildReportsAsyncとしてマークされているが、Awaitを使用していないため、コンパイラは、あなたにそのコードとエラーを与えるべきです。

「非同期」はではありません。は「バックグラウンドスレッドで実行」を意味します。したがって、同期コードを非同期化する方法はありません。コード自体は本質的に同期的または非同期的である。

たとえば、自然に非同期のデータベース操作(たとえば、Entity Frameworkを使用)がある場合、自然に非同期のBuildReportsを持つことができます。ただし、DataTable APIは非同期には対応していないため、DataTableには非同期APIがまったくありません。同期的な世界でしっかりと立ち往生しています。

具体的には、既存の同期コードをバックグラウンドスレッドで実行するのが最適です(これはTask.Runで実行できます)。その後、はそれが非同期を消費することができます

Private Async Sub btnClearAll_Click(sender As Object, e As System.EventArgs) Handles btnClearAll.Click 
    Await Task.Run(Function() BuildReports()) 
    ClearAll() 
End Sub 

Private Sub BuildReports() 
... 
+0

おかげでスティーブンを。あなたが提案した変更を行う "Expressionは値を生成しません"と表示しています:Task.Run(Function()BuildReports())を待ちます。何か案は? – JackW9653

+0

@ JackW9653:申し訳ありませんが、それは 'Function'ではなく、匿名' Sub'でなければなりません。 –

+0

作品は完璧です!ありがとう@Stephen。あなたの記事のいくつかを読んだことがありますが、今後のプロジェクトでAsync/Awaitを使用するための良い説明をお聞かせください。助けてくれてありがとう。 – JackW9653

関連する問題