C# WUApiLib - загрузка и установка асинхронно
Я программирую, используя библиотеку WUApiLib от Microsoft. Я написал простое приложение, которое ищет все обновления программного обеспечения, которые не установлены, а затем загружает и устанавливает их. Эта часть работает отлично (я использовал код, найденный здесь, чтобы помочь: http://www.nullskull.com/a/1592/install-windows-updates-using-c--wuapi.aspx).
Однако я хочу использовать функциональные возможности библиотеки BeginDownload, EndDownload, BeginInstall, EndInstall библиотеки, чтобы она могла сообщать о ходе выполнения обратно в интерфейс. Функции в этой статье являются синхронными, а функции, о которых я упоминаю, являются асинхронными.
Я использую первый ответ на этой странице в качестве шаблона: C# и WUAPI: функция BeginDownload
Тем не менее, моя функция Invoke() никогда не вызывается, и я не могу понять, почему.
iUpdateDownloader_onProgressChanged progress = new iUpdateDownloader_onProgressChanged(this);
IDownloadJob downloadJob = downloader.BeginDownload(progress, new iUpdateDownloader_onCompleted(this), new iUpdateDownloader_state(this));
public class iUpdateDownloader_onProgressChanged : IDownloadProgressChangedCallback
{
private frmMain form1;
public iUpdateDownloader_onProgressChanged(frmMain mainForm)
{
this.form1 = mainForm;
}
// Implementation of IDownloadProgressChangedCallback interface...
public void Invoke(IDownloadJob downloadJob, IDownloadProgressChangedCallbackArgs e)
{
decimal bDownloaded = ((e.Progress.TotalBytesDownloaded / 1024) / 1024);
decimal bToDownloaded = ((e.Progress.TotalBytesToDownload / 1024) / 1024);
bDownloaded = decimal.Round(bDownloaded, 2);
bToDownloaded = decimal.Round(bToDownloaded, 2);
form1.setDownloadProgressText("Downloading Update: "
+ e.Progress.CurrentUpdateIndex
+ "/"
+ downloadJob.Updates.Count
+ " - "
+ bDownloaded + "Mb"
+ " / "
+ bToDownloaded + "Mb");
}
}
Я могу поставить точку останова на первой строке в функции Invoke, и она там никогда не достигнет.
Есть идеи?
1 ответ
Первое, что я замечаю, что это неправильно: вызов form1.setDownloadProgressText - это вызов пользовательского интерфейса, созданный из другого асинхронного потока. Вы захотите обернуть это в this.Invoke (если WinForms) или Dispatcher.Invoke (если WPF), чтобы перенаправить манипуляции пользовательского интерфейса в поток пользовательского интерфейса.
Кроме того, переменная "this" недоступна в списке объявлений переменных-членов, которые встречаются перед функцией конструктора, поэтому
iUpdateDownloader_onProgressChanged progress = new iUpdateDownloader_onProgressChanged(this);
IDownloadJob downloadJob = downloader.BeginDownload(progress, new
iUpdateDownloader_onCompleted(this), new iUpdateDownloader_state(this));
не будет работать, если он не обернут в конструктор или обработчик события загрузки формы, который здесь не показан.
Мое предположение, что ваш национальный объект вызывается перед тем, как показано здесь, и он пытается манипулировать формой из темы, а не одним пользовательским интерфейсом, и этот всплеск предотвращает возникновение других проблем в этом контексте (включая) ИЗ КОГДА-ЛИБО ПРИЗНАННОГО.