2016-04-27 19 views
1

我的函數有三個部分。如何使用異步任務創建Reportviewer

第一部分參數彈出

第二部分執行的代碼在一個新的線程與ApartmentState.STA打開。 3

部分 - 顯示的ReportViewer

我目前收到此錯誤the calling thread cannot access this object because a different thread owns it.

public async void AnticipatedEntriesReport(bool fund) 
{ 
    var anticipatedReport = new AnticipatedReport(fund); 
    ReportPreviewForm report = new ReportPreviewForm(); 
    anticipatedReport.InitializeParameters(); 
    if (anticipatedReport.GetParameters() != null) 
    { 
     await RunAsyncTask(
      () => 
      { 
       report = anticipatedReport.GenerateReport(SelectedLoans); 
      }); 

     report.Show(); 
    } 
} 

我的代碼處斷裂report.Show()。

expectedReport.GenerateReport返回一個ReportPreviewForm。

我想知道我做錯了什麼?我認爲這是基於我創建對象的位置。

public async Task RunAsyncTask(System.Action action) 
{  
    try 
    { 
     await ThreadManager.StartSTATask(action); 
    } 
    catch (Exception ex) 
    {   

    }   
} 

public static Task StartSTATask(System.Action func) 
{ 
    var tcs = new TaskCompletionSource<object>(); 
    var thread = new Thread(() => 
    { 
     try 
     { 
      func(); 
      tcs.SetResult(null); 
     } 
     catch (Exception e) 
     { 
      tcs.SetException(e); 
     } 
    }); 
    thread.SetApartmentState(ApartmentState.STA); 
    thread.Start(); 
    return tcs.Task; 
} 
+0

爲什麼能你是否將報告作爲任務的結果返回? – shlatchz

+0

什麼是'RunAsyncTask'? –

+0

@StephenCleary嗨,我更新它包括RunAsyncTask方法 – Master

回答

0

只需創建裏面的任務報告,並將其返回任務的父:

public async Task AnticipatedEntriesReport(bool fund) 
{ 
    var anticipatedReport = new AnticipatedReport(fund); 
    ReportPreviewForm report = null; 
    anticipatedReport.InitializeParameters(); 
    if (anticipatedReport.GetParameters() != null) 
    { 
     // Generate the report inside the task and return it. 
     report = await RunAsyncTask(
      () => 
      { 
       var result = anticipatedReport.GenerateReport(SelectedLoans); 
       return result; 
      }); 
    } 
} 

和RunAsyncTask:

public async Task<TResult> RunAsyncTask<TResult>(Func<TResult> function) 
{ 
    TResult result = default(TResult); 
    UpdateBusyUi(true); 
    try 
    { 
     result = await ThreadManager.StartSTATask(function); 
    } 
    catch (Exception ex) 
    { 
     SendException(ex); 
     LoadSucceed = false; 
     Events.PublishOnUIThread(new BackgroundCompletedEvent { Header = BackgroundCompletedEvent.EntityActions.Error, Error = true }); 
    } 
    UpdateBusyUi(false); 
    return result; 
} 

的StartSTATask:

Task<TResult> StartSTATask<TResult>(Func<TResult> function) 
{ 
    TaskCompletionSource<TResult> source = new TaskCompletionSource<TResult>(); 
    Thread thread = new Thread(() => 
     { 
      try 
      { 
       source.SetResult(function()); 
      } 
      catch (Exception ex) 
      { 
       source.SetException(ex); 
      } 
     }); 
    thread.SetApartmentState(ApartmentState.STA); 
    thread.Start(); 
    return source.Task; 
} 
+0

此處同樣錯誤「調用線程必須是STA,因爲許多UI組件都需要這個。」這次它不會觸及report.show() – Master

+0

你爲什麼要用'ApartmentState.STA'運行該方法? – shlatchz

+0

因爲這是一個可重用的方法,如果我想更新UI中的某些項目,ApartmentState.STA將允許我...... – Master