2014-10-08 5 views
0

Я программирую с использованием библиотеки WUApiLib от Microsoft. Я написал простое приложение, которое ищет все обновления программного обеспечения, которые не установлены, а затем загружает и устанавливает их. Эта часть работает отлично (я использовал код, найденный здесь, чтобы помочь: http://www.nullskull.com/a/1592/install-windows-updates-using-c--wuapi.aspx).C# WUApiLib - Загрузка и установка асинхронно

Тем не менее, я хочу использовать функциональность BeginDownload, EndDownload, BeginInstall, EndInstall библиотеки, чтобы она могла сообщать о прогрессе в интерфейсе. Функции в этой статье являются синхронными, и упомянутые функции являются асинхронными.

Я использую первый ответ на эту страницу как шаблон: C# and WUAPI: BeginDownload function

Однако функция моя 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, и она никогда не доходит до нее.

Любые идеи?

ответ

0

Первое, что я замечаю, что это неправильно: вызов form1.setDownloadProgressText - это вызов пользовательского интерфейса, созданного из другого асинхронного потока. Вы захотите обернуть это в this.Invoke (если WinForms) или Dispatcher.Invoke (если WPF) для маршалирования пользовательского интерфейса в поток пользовательского интерфейса.

Кроме того, «это» переменная не доступна в списке объявлений переменных члена, которые возникают перед функцией конструктора, так

iUpdateDownloader_onProgressChanged progress = new iUpdateDownloader_onProgressChanged(this); 
    IDownloadJob downloadJob = downloader.BeginDownload(progress, new  
    iUpdateDownloader_onCompleted(this), new iUpdateDownloader_state(this)); 

не будет работать, если она не обернута в конструкторе или форме load event handler, который не изображен здесь.

моя догадка, ЧТО О государственных ОБЪЕКТ становится Вызывается ПЕРЕД ОДНОЙ УКАЗАННОЙ ЗДЕСЬ, И ЭТО ПОПЫТКА манипулируют формы из потока, отличного пользовательского интерфейса ONE, и это раздутие препятствующей других объектов (в том числе ОДИН ОТПУСКАЕТСЯ ЗДЕСЬ) ОТ ВКЛЮЧЕНИЯ.

+0

Итак, вместо этого, что бы вы прошли? – Stephen

+0

Вы передали бы «это», но вы сделали бы это внутри функции, например, в конце обработчика событий загрузки формы, когда ваши части пользовательского интерфейса (которые упоминаются в реализациях интерфейса) были добавлены в окно (InitializeComponent делает это). Тем не менее, большая часть функций манипулирования пользовательским интерфейсом связана с потоком пользовательского интерфейса. Опять же, я думаю, что объект реализации onState может вызывать ошибку, не выполнив этого, и ошибка останавливает все. –

+0

Если вам нужна дополнительная информация, не стесняйтесь спрашивать, и я попытаюсь уточнить. –