2016-04-27 16 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