Я уже некоторое время развертываю обновления для моего приложения с ClickOnce. Хотя я рад, что могу делать улучшения, я немного разочарован текущим индикатором выполнения. Немного предыстории - у меня есть класс окна XAML под названием «UpdateProgress», который я открываю, когда выполняется обновление для приложения. Вот текущий фрагмент кода, который я сейчас использую, который, по крайней мере, уведомляет пользователя о том, что прогресс выполняется без замораживания приложения / сбоя, но НЕ визуально обновляет индикатор выполнения:
case UpdateStatuses.UpdateAvailable:
DialogResult dialogResult = System.Windows.Forms.MessageBox.Show("An update is available. Would you like to update the application now?", "Update available", MessageBoxButtons.OKCancel);
if (dialogResult.ToString() == "OK")
{
BackgroundWorker bgUpdate = new BackgroundWorker();
UpdateProgress updateNotify = new UpdateProgress();
bgUpdate.WorkerReportsProgress = true;
bgUpdate.DoWork += (uptSender, uptE) => { UpdateApplication();};
bgUpdate.ProgressChanged += (progSender, progE) => { updateNotify.updateProgress.Value = progE.ProgressPercentage; };
bgUpdate.RunWorkerCompleted += (comSender, comE) => {
updateNotify.Close();
applicationUpdated();
};
updateNotify.Show();
bgUpdate.RunWorkerAsync();
}
break;
По сути, я создаю фоновый рабочий выше, который запускает код ниже:
private static void UpdateApplication()
{
try
{
ApplicationDeployment updateCheck = ApplicationDeployment.CurrentDeployment;
//BackgroundWorker bgWorker = new BackgroundWorker();
//UpdateProgress updateNotify = new UpdateProgress();
//updateCheck.UpdateProgressChanged += (s, e) =>
//{
// updateNotify.updateProgress.Value = e.ProgressPercentage;
//};
//bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(UpdateComponent.noteUpdates);
//bgWorker.RunWorkerAsync();
//updateCheck.UpdateCompleted += (s, e) =>
//{
// updateNotify.Close();
// applicationUpdated();
//};
//updateNotify.Dispatcher.InvokeAsync(() =>
// {
//updateNotify.Show();
updateCheck.Update();
//});
//return null;
}
catch (DeploymentDownloadException dde)
{
System.Windows.MessageBox.Show("Cannot install the latest version of the application. Please check your network connection, or try again later. Error: " + dde);
//return null;
}
}
Краткое объяснение, в настоящее время я только создаю экземпляр ApplicationDeployment под названием updateCheck и просто запускаю обновление в этой теме. То, что я пытался сделать раньше, - это загрузка некоторого прокомментированного кода ниже, только чтобы увидеть сбой приложения при обновлении. Оказывается, при отладке с экземпляром PROD моего приложения это происходит из-за следующей ошибки:
Вызывающий поток не может получить доступ к этому объекту, поскольку он принадлежит другому потоку.
Теперь, немного покопавшись, я видел довольно много хороших отзывов об этом. Насколько я понимаю, отчасти проблема в том, что я пытаюсь запустить этот код из статического класса, отделенного от моего MainWindow и других классов пользовательского интерфейса. Я делаю это, чтобы сохранить мой код чистым и модульным, но, очевидно, это имеет свою цену. Я понимаю, что можно связать процент прогресса индикатора выполнения, если он находится в коде позади, скажем, окна индикатора выполнения, но что, если я пытаюсь придерживаться этого в статическом классе, о котором я говорю вместо этого? Я пытался использовать такие вещи, как методы Dispatcher / BeginInvoke (), но, к сожалению, в итоге получился тот же результат.
Может ли кто-нибудь дать мне лучшее предложение о том, как обновить ход выполнения моего индикатора выполнения в окне с процентом хода выполнения процедуры обновления экземпляра ApplicationDeployment?
Заранее большое спасибо.