2017-07-18 11 views
0

私はWIXインストーラを持っています。そのダイアログの1にカスタムアクションを呼び出すボタンがあります:WIX C#非同期のカスタムアクション

<Control X="15" Y="65" Width="100" Height="15" Type="PushButton" Id="SetUp" Text="Set up" TabSkip="yes"> 
    <Publish Event="DoAction" Value="CheckingConfig" Order="3">1</Publish> 
</Control> 

CheckingConfigは、C#のカスタムアクションです:

[CustomAction] 
public static ActionResult CheckingConfig(Session session) 
{ 
    try 
    { 
     session.StartLog("CheckingConfig"); 

     CheckConfiguration(session); 

     return ActionResult.Success; 
    } 
    finally 
    { 
     session.EndLog("CheckingConfig", ActionResult.Success); 
    } 
} 

private static async void CheckConfiguration(Session session) 
{ 
    CheckXmlConfig(); 
    CheckTxtConfig(); 

    await CheckDbConfig(session); 

    CheckXlsConfig(); 
} 

private static async Task<int> CheckDbConfig(Session session) 
{ 
    // DbList = new List<ConfigEntity>(); 
    // read from db to list ... 

    try 
    { 
     var tasks = DbList.Select(r => AsyncTask(r.Value)).ToList(); 

     session.InfoLog("...before when all"); 
     await Task.WhenAll(tasks); 
     session.InfoLog("...after when all"); 
    } 
    catch (Exception e) 
    { 
     session.ErrorLog(e.ToString()); 
    } 

    return 0; 
} 

private static Task AsyncTask(string value) 
{ 
    return Task.Run(() => 
    { 
     // ... 
    }); 
} 

そして、私はインストーラを実行し、ボタンを押してください - 私はThreadAbortExceptionのを受けます。 WIXは、ボタンクリックでカスタムアクションで非同期をサポートしますか? CheckDbConfigを非同期にしないようにして、Task.WaitAll(tasks、10000)を使用しようとしました。しかし、Task.WaitAll(タスク)を時間なしで使用すると、プログラムはすべてのタスクの実行が完了するまで待つことなく、すべてのタスクが完了する前にCheckXlsConfig()を実行します。私は、タスクが完了するまでの正確な時間を知らない。コードを動作させるにはどうすればよいですか?

答えて

0

これは、コントロールをインストールに戻そうとする前に、すべての非同期タスクが完了していないということを理解しているようです。私は非同期のエキスパートではありませんが、これを修正するには2つのオプションのいずれかに傾倒してください。

  1. CheckingConfigであなたのコードの最も外側のレベルで修正これを、:あなたが結果を必要としない場合

    session.StartLog("CheckingConfig"); 
    CheckConfiguration(session); 
    return ActionResult.Success; 
    

    session.StartLog("CheckingConfig"); 
    CheckConfiguration(session).Wait(); 
    return ActionResult.Success; 
    
  2. のようなものに置き換えることができますインストールのUI、カスタムアクション呼び出しを非同期にして(インストールを待つ必要はありません)、内部ですべてのコードを同期的に実行することを検討してください。あなたのコードは、AsyncTaskの実装でTask.Runを使用することを前提として、偽の非同期のみであるようです。

関連する問題