【问题标题】:C# WUApiLib - Download and Install AsynchronouslyC# WUApiLib - 异步下载和安装
【发布时间】:2014-12-03 07:40:12
【问题描述】:

我正在使用 Microsoft 的 WUApiLib 库进行编程。我编写了一个简单的应用程序,它搜索所有未安装的软件更新,然后下载并安装它们。这部分运行良好(我使用此处找到的代码来提供帮助:http://www.nullskull.com/a/1592/install-windows-updates-using-c--wuapi.aspx)。

但是,我想利用库的 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 函数的第一行设置一个断点,但它永远不会到达那里。

有什么想法吗?

【问题讨论】:

    标签: c# winapi asynchronous visual-studio-2013 windows-update


    【解决方案1】:

    我注意到的第一件事是错误的:对 form1.setDownloadProgressText 的调用是对从不同的异步线程进行的 UI 的调用。您需要将其包装在 this.Invoke(如果是 WinForms)或 Dispatcher.Invoke(如果是 WPF)中,以将 UI 操作编组到 UI 线程。

    另外,“this”变量在构造函数之前的成员变量声明列表中不可用,所以

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

    除非它被包装在构造函数或表单加载事件处理程序中,否则它将无法工作,此处未显示。

    我的猜测是您的 onState 对象在此处显示的对象之前被调用,并且它正在尝试从 UI 之外的线程操作表单,并且此爆炸正在阻止其他对象(包括那个在这里描述)从被调用。

    【讨论】:

    • 那么,除了通过这个,你会通过什么?
    • 你会传递“this”,但你会在一个函数中执行它,例如在表单加载事件处理程序的末尾,当你的 UI 片段(在你的接口实现中引用)有已添加到窗口中(InitializeComponent 会这样做)。不过,最重要的是将 UI 操作函数编组到 UI 线程。同样,我认为 onState 实现对象可能会因未能执行此操作而导致错误,并且该错误会停止一切。
    • 如果您需要更多信息,请不要犹豫,我会尽力进一步澄清。
    • 您必须原谅我,但我通常是一名 PHP 程序员,而不是 C#,所以很多事情让我有点不知所措。当您说我应该在表单加载函数中声明 iDownloadJob 而不是我拥有它并使其成为表单的成员时,我想我的理解是正确的?
    猜你喜欢
    • 2018-08-22
    • 1970-01-01
    • 2012-08-19
    • 2015-12-19
    • 2011-05-31
    • 1970-01-01
    • 2016-08-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多