【问题标题】:c++/cli wpf set property on ui thread from different threadc++/cli wpf在不同线程的ui线程上设置属性
【发布时间】:2014-08-07 21:40:09
【问题描述】:

这里有一些示例代码可以更好地说明我在这里想要完成的工作。 基本上我需要设置只能从 UI 线程设置的属性。有什么想法吗?

public ref class ExtendedImage : public System::Windows::Controls::Image
    {
public:
    void SetImageFromUrl (System::String^ url)
        {
         if (!System::Uri::TryCreate (path, System::UriKind::Absolute, this->m_uri) || this->m_uri->IsFile)
            return;

        System::Threading::Thread^ downloadImage = gcnew System::Threading::Thread (gcnew System::Threading::ThreadStart (this, &ExtendedImage::DownloadAndSetImage));
        downloadImage->Start ();
        }

private:
    System::Uri^ m_uri;

    void DownloadAndSetImage ()
        {
        System::Windows::Media::Imaging::BitmapImage^ bitmap = gcnew System::Windows::Media::Imaging::BitmapImage (this->m_uri);

        //execute this->Source = bitmap; on UI thread
        }
    }

更新: 结合问题代码以正确答案 C# 解决方案后的一些有用信息。要获取 UI 线程调度程序,请使用 System::Windows::Application::Current->Dispatcher

【问题讨论】:

    标签: wpf multithreading c++-cli ui-thread


    【解决方案1】:

    从 URI 创建 BitmapImage 已由 WPF 异步执行,因此无需启动另一个线程。

    就这样做吧:

    using namespace System;
    using namespace System::Windows::Controls;
    using namespace System::Windows::Media::Imaging;
    
    public ref class ExtendedImage : public Image
    {
    public:
        void SetImageFromUrl(System::String^ url)
        {
            Uri^ uri;
    
            if (Uri::TryCreate(url, UriKind::Absolute, uri) && !uri->IsFile)
            {
                Source = gcnew BitmapImage(uri);
            }
        }
    };
    

    无论如何,如果您确实需要从 URI 手动下载图像缓冲区并在单独的线程中从该缓冲区创建 BitmapImage,您可以按照this answer 中显示的方法处理类似问题。

    【讨论】:

    • 您的回答使我对此进行了更多研究,因为如果我按照您建议的方式进行操作,UI 就会冻结(基本上这是我遇到冻结 UI 问题并决定时尝试的第一件事使用线程,但是,当然,我在你回答后再次尝试,只是为了确保。)看起来它不是由 WPF 自动完成的,除非依赖属性绑定选项 IsAsync 设置为 true。我相信这很重要。不管怎样,就我而言,我不能使用 XAML,所以必须在代码中完成。
    • 所以为了弄乱绑定,我必须重写 OnApplyTemplate,然而,奇怪的是它没有被调用(但这是另一个问题)。另外对于设置图像源属性,我只希望它在 uri 路径为 URL 时是异步的。那么,如果您知道我如何做到这一点,您能否更新您的答案?我已经想出了如何让它与线程一起工作,但你的答案,如果你会更新它以使其清楚 - 我相信会更合适。
    • 不知道您在这里谈论的是哪些绑定。您的问题只有一个 SetImageFromUrl 方法。除非 URL 不引用本地文件,否则 WPF 将异步加载图像。
    • 这是 C# stackoverflow.com/questions/16035300/make-wpf-image-load-async 中的一个类似问题,得分最高的答案告诉如何使用 XAML 进行操作,但是正如我所提到的,在我的情况下我不能使用 XAML。并且 URL 不引用本地文件。事实上!uri->IsFile 会处理它,因为如果它是本地文件,它将失败。尽管我希望它是真的,但它不是自动完成的,无响应的 UI 证明了这一点。
    • 那么您可能只是按照my answer 中给出的建议来解决同一个问题。还请仔细查看高度赞成的答案中的 cmets,关于绑定转换器不被异步调用这一事实,即使绑定的 IsAsync 属性设置为 true。即使答案得票最多,它也不能解决问题中提出的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多