【问题标题】:Locally downloading multiple image files本地下载多个图像文件
【发布时间】:2018-02-27 16:25:21
【问题描述】:

我正在从网页中提取一个 JSON 字符串,其中包含一个对象列表。每个对象中有两个字符串,它们都包含指向图像的链接。我想在本地下载这张图片。

我目前正在使用每隔几秒触发一次的异步函数,并在 JSON 中查找以前不在列表中的任何新对象,获取图像链接,然后像这样下载它们:

using (WebClient webClient = new WebClient())
{
    await webClient.DownloadFileTaskAsync(new Uri(object.AvatarImage), System.IO.Directory.GetCurrentDirectory() + "\\Elements" + "\\" + object.PostID.Replace(':', '-') + "_avatar.png");
}

using (WebClient webClient = new WebClient())
{
    await webClient.DownloadFileTaskAsync(new Uri(object.Media), System.IO.Directory.GetCurrentDirectory() + "\\Elements" + "\\" + object.PostID.Replace(':', '-') + "_media.png");
}

这可以正常工作,直到我收到大量图像,此时我有时会收到错误:

进程无法访问文件“path”,因为它正被另一个进程使用。

我没有在其他任何地方操作文件,虽然图像路径确实绑定到图像控件,但如果我破坏绑定,我仍然会遇到同样的错误。

这可能是什么原因造成的?

【问题讨论】:

标签: c# wpf asynchronous webclient


【解决方案1】:

您是否使用 System.Timers.Timer 触发下载? 您是否将计时器设置为 AutoReset=true? 那么可能会在第一次调用完成之前再次调用下载方法。

来自https://msdn.microsoft.com/en-us/library/system.timers.timer.autoreset(v=vs.110).aspx

"如果 SynchronizingObject 属性为 null,则在 ThreadPool 线程上引发 Elapsed 事件。如果 Elapsed 事件的处理持续时间超过 Interval,则该事件可能会在另一个 ThreadPool 线程上再次引发。在这种情况下,事件处理程序应该是可重入的。”

一种解决方案是将 AutoReset 设置为 false 并在下载完成后始终调用计时器 Start() 方法。进行足够的错误处理很重要,这样 Start() 方法的调用不会被未处理的异常阻止。

【讨论】:

  • 我现在正在使用 System.Windows.Forms.Timer。是否值得切换?
  • 你不需要切换。正如我在文档中看到的那样, System.Windows.Forms.Timer 是单线程的。但是您提到您正在使用异步功能来下载图像。我认为您必须使用阻塞功能。您能否发布计时器经过事件处理程序中的代码部分,以显示您如何调用下载方法?
猜你喜欢
  • 2022-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-04
  • 2015-10-25
  • 2017-01-13
  • 1970-01-01
  • 2020-11-13
相关资源
最近更新 更多