gpt4 book ai didi

wpf - 在 WPF 的后台线程中加载图像

转载 作者:行者123 更新时间:2023-12-03 13:31:02 25 4
gpt4 key购买 nike

在这个网站和其他论坛上已经有很多关于这个的问题,但我还没有找到真正有效的解决方案。

这是我想要做的:

  • 在我的 WPF 应用程序中,我想加载图像。
  • 图片来自网络上的任意 URI。
  • 图像可以是任何格式。
  • 如果我多次加载相同的图像,我想使用标准的 Windows Internet 缓存。
  • 图像加载和解码应该同步发生,但不是在 UI 线程上。
  • 最后,我应该得到一些可以应用于 的源属性的东西。

  • 我尝试过的事情:
  • 在 BackgroundWorker 上使用 WebClient.OpenRead()。工作正常,但不使用缓存。 WebClient.CachePolicy 只影响那个特定的 WebClient 实例。
  • 在 Backgroundworker 上使用 WebRequest 而不是 WebClient,并设置 WebRequest.DefaultCachePolicy。这正确地使用了缓存,但我还没有看到一个例子,它不会给我一半的时间看起来损坏的图像。
  • 在 BackgroundWorker 中创建 BitmapImage,设置 BitmapImage.UriSource 并尝试处理 BitmapImage.DownloadCompleted。如果设置了 BitmapImage.CacheOption,这似乎使用缓存,但似乎没有办法处理 DownloadCompleted,因为 BackgroundWorker 立即返回。

  • 几个月来我一直在断断续续地挣扎,我开始认为这是不可能的,但你可能比我聪明。你怎么看?

    最佳答案

    BitmapImage 需要对其所有事件和内部的异步支持。在后台线程上调用 Dispatcher.Run() 将......很好地运行线程的调度程序。 (BitmapImage 继承自 DispatcherObject,因此它需要一个调度程序。如果创建 BitmapImage 的线程还没有调度程序,则将根据需要创建一个新的调度程序。很酷。)。

    重要的安全提示:如果 BitmapImage 从缓存中提取数据(老鼠),它不会引发任何事件。

    这对我来说效果很好......

         var worker = new BackgroundWorker() { WorkerReportsProgress = true };

    // DoWork runs on a brackground thread...no thouchy uiy.
    worker.DoWork += (sender, args) =>
    {
    var uri = args.Argument as Uri;
    var image = new BitmapImage();

    image.BeginInit();
    image.DownloadProgress += (s, e) => worker.ReportProgress(e.Progress);
    image.DownloadFailed += (s, e) => Dispatcher.CurrentDispatcher.InvokeShutdown();
    image.DecodeFailed += (s, e) => Dispatcher.CurrentDispatcher.InvokeShutdown();
    image.DownloadCompleted += (s, e) =>
    {
    image.Freeze();
    args.Result = image;
    Dispatcher.CurrentDispatcher.InvokeShutdown();
    };
    image.UriSource = uri;
    image.EndInit();

    // !!! if IsDownloading == false the image is cached and NO events will fire !!!

    if (image.IsDownloading == false)
    {
    image.Freeze();
    args.Result = image;
    }
    else
    {
    // block until InvokeShutdown() is called.
    Dispatcher.Run();
    }
    };

    // ProgressChanged runs on the UI thread
    worker.ProgressChanged += (s, args) => progressBar.Value = args.ProgressPercentage;

    // RunWorkerCompleted runs on the UI thread
    worker.RunWorkerCompleted += (s, args) =>
    {
    if (args.Error == null)
    {
    uiImage.Source = args.Result as BitmapImage;
    }
    };

    var imageUri = new Uri(@"http://farm6.static.flickr.com/5204/5275574073_1c5b004117_b.jpg");

    worker.RunWorkerAsync(imageUri);

    关于wpf - 在 WPF 的后台线程中加载图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5439042/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com