私のWPFアプリケーションでは、使用可能な新しいバージョンを確認する起動時にクイックルーチンを実行する必要があります。バージョンが利用可能な場合は、アップデートを行い、直ちにアプリを再起動します。これは、メインウィンドウがユーザーに表示される前に実行されるため、アプリケーションが起動するまでにもう2分の1を要したように見えます。UI以外のスレッドからWPFアプリケーションを再起動
私たちはアップデータとしてSquirrel.Windowsを使用しています。私は以下のクラスで更新のチェック/更新を処理するようにしました。
public class UpdateVersion
{
private readonly UpdateManager _updateManager;
public Action<int> Progress;
public event Action Restart;
public UpdateVersion(string squirrelUrl)
{
_updateManager = new UpdateManager(squirrelUrl);
}
public async Task UpdateVersions()
{
using (_updateManager)
{
UpdateInfo updateInfo = await _updateManager.CheckForUpdate(progress:Progress);
if (updateInfo.CurrentlyInstalledVersion == null)
{
if (updateInfo.FutureReleaseEntry != null)
{
await _updateManager.UpdateApp(Progress);
// Job crashes here
Restart?.Invoke();
}
}
else if (updateInfo.CurrentlyInstalledVersion.Version < updateInfo.FutureReleaseEntry.Version)
{
await _updateManager.UpdateApp(Progress);
// Job crashes here
Restart?.Invoke();
}
}
}
}
残念ながら、リスはCheckForUpdate
とUpdateApp
方法は、全体のupdateメソッドを非同期になって、await
を使用しなければならないことを意味している、唯一の彼らの更新プロセスasync
を行いました。 Task
にasnycコールを割り当て、次にアップデートを完了するために単に.Wait()
を割り当てます。
アプリを再起動しようとすると問題が発生します。私が読んだことに基づいて、私はDispatcher.Invoke
を使用して、私がアップデートを実行するときにUI以外のスレッド上にあるため、再起動を呼び出す必要があります。
異なるスレッドが
正しくするためにDispatcher.Invoke
を実装する方法任意のアイデアを、それを所有しているので、呼び出し元のスレッドがこのオブジェクトにアクセスすることはできません。ただし、以下のコードにもかかわらず、私はまだ同じエラーメッセージが表示されますアプリを再起動しますか?
// Instantiate new UpdateVersion object passing in the URL
UpdateVersion updateVersion = new UpdateVersion(System.Configuration.ConfigurationManager.AppSettings.Get("SquirrelDirectory"));
// Assign Dispatch.Invoke as Restart action delegate
updateVersion.Restart +=() =>
{
Dispatcher.Invoke(() =>
{
Process.Start(ResourceAssembly.Location);
Current.Shutdown();
});
};
// This is here for debugging purposes so I know the update is occurring
updateVersion.Progress += (count) =>
{
Debug.WriteLine($"Progress.. {count}");
};
var task = Task.Run(async() => { await updateVersion.UpdateVersions(); });
task.Wait();
EDIT以下
はRestart
アクションのTarget
属性のスクリーンショットです。デバッガは上のRestar?.Invoke
行で一時停止しました。
、それはあなたのプログラムです。 csか 'Application'イベントですか? – CodingGorilla
Program.csファイルがありません。アプリケーションの 'OnStartup'メソッドです。プログラムが最初に実行するコマンドです。 – NealR
'Program.cs'を' Main'メソッド(コンソールアプリケーションのような)で追加し、それをあなたのスタートアップオブジェクト(プロパティ - >アプリケーションの下)に設定してそこから更新してください。そうすることで、実行する更新があるときにメインウィンドウを起動しないようにすることができます。 – CodingGorilla