c++ - 等待 DownloadFileAsync 与 ManualResetEvent c++/cli

标签 c++ .net command-line-interface manualresetevent downloadfileasync

我在使用 Windows 窗体应用程序的 C++/CLI 中遇到了一个小但令人沮丧的问题。

所以问题是我必须使用 WebClient istance 从网络服务器下载文件。通常我使用 DownloadFile 而不是 DownoadFileAsyn,但是如果我想显示一个显示下载文件进度的进度条,我必须使用 DownloadFileAsyn。那么我怎样才能等到下载过程完成呢?

代码是:

    ref class Example{

    private:

        static System::Threading::ManualResetEvent^ mre = gcnew System::Threading::ManualResetEvent(false);

    public:

        void Download();
        void DownloadFileCompleted(Object^ sender, System::ComponentModel::AsyncCompletedEventArgs^ e);
    };






void Example::Download(){

    WebClient^ request = gcnew WebClient;
    request->Credentials = gcnew NetworkCredential("anonymous", "anonymous");

    request->DownloadFileCompleted += gcnew System::ComponentModel::AsyncCompletedEventHandler(this,&FileCrypt::DownloadFileCompleted);

    request->DownloadFileAsync(gcnew Uri("ftp://ftp...."+remote_path),remote_file,mre);
    mre->WaitOne();


/*
BLOCK OF INSTRUCTIONS THAT I WANT TO RUN AFTER THE FILE DOWNLOAD IS COMPLETED

*/
}

void Example::DownloadFileCompleted(Object^ sender, System::ComponentModel::AsyncCompletedEventArgs^ e){
    MessageBox::Show("COMPLETED");
    mre->Set();
}

因此当下载完成后,程序停止运行并且它不会运行上面编写的指令 block ,在 mre->WaitOne() 指令之后。 DownloadFileCompleted() 未执行,实际上甚至显示了消息框。

有什么想法吗?我已经搜索过这个问题,很多人都遇到过,但仅限于 c#。我刚刚将解决方案从 C# 翻译成 C++。但它不起作用...

最佳答案

你不能等待,这会导致死锁。 DownloadFileCompleted() 方法无法运行,直到您的主线程空闲并重新进入调度程序循环。但它并没有闲置,而是卡在了 WaitOne() 调用中。因此该方法无法运行,无法设置 MRE。这反过来又导致 WaitOne() 永远无法完成。一个你的程序永远无法恢复的致命拥抱。标准线程错误之一。

不清楚为什么您要等待,正如发布的那样,WaitOne() 调用根本没有意义。您可以简单地删除它,一切正常。也许在您的实际程序中实际上在它之后有一些代码,您必须将该代码移到 DownloadFileCompleted() 方法中。

此处适用显示 UI 的线程的一般编程规则。它永远不会休眠,也永远不会阻塞。这样做会使 UI 无响应并显着增加死锁的可能性。 UI 是事件驱动的,例如用户移动鼠标或按下某个键时触发的事件。触发事件时运行的代码只能在线程未执行任何其他操作时运行。下载完成也作为事件发出信号。

关于c++ - 等待 DownloadFileAsync 与 ManualResetEvent c++/cli,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29316244/

相关文章:

python - 如何在 Python 的 struct 中使用 C++ struct

c++ - map 编辑器性能建议

android - 由于 NDK 路径中的反斜杠,Qt Creator 无法构建 Android 库

c++ - CLR ICLRControl::GetCLRManager 失败并出现错误 HOST_E_INVALIDOPERATION

.net - IEqualityComparer<double> 带有容差;如何实现GetHashCode?

linux - Codeigniter cron 作业问题

c++ - 合并的正确语法

.net - 带有.Net的Oracle高级队列

c - 在 Linux 上将密码从 GUI 传递到 CLI。

Ubuntu CLI 批量查找 CP