0

对不起,如果标题不清楚或不正确,不知道我应该放什么标题。如有错误请指正。
我有这个代码可以从 IP 摄像机下载图像,它可以下载图像。
问题是,如果我有两个或多个摄像头,如何同时为所有摄像头执行图像下载过程?

private void GetImage()
{
   string IP1 = "example.IPcam1.com:81/snapshot.cgi;
   string IP2 = "example.IPcam2.com:81/snapshot.cgi;
   .
   .
   .
   string IPn = "example.IPcamn.com:81/snapshot.cgi";

   for (int i = 0; i < 10; i++)
   {
       string ImagePath = Server.MapPath("~\\Videos\\liveRecording2\\") + string.Format("{0}", i, i + 1) + ".jpeg";
       string sourceURL = ip;
       WebRequest req = (WebRequest)WebRequest.Create(sourceURL);
       req.Credentials = new NetworkCredential("user", "password");
       WebResponse resp = req.GetResponse();
       Stream stream = resp.GetResponseStream();
       Bitmap bmp = (Bitmap)Bitmap.FromStream(stream);
       bmp.Save(ImagePath);
   }
}
4

2 回答 2

3

您不应该从 ASP.NET 应用程序中运行像这样的长时间运行的代码。它们旨在简单地响应请求。

您应该将此代码放在服务中(Windows 服务很简单),并通过在其中运行的 WCF 服务来控制服务。

你也会遇到麻烦,因为你没有using块中的 WebResponse 和 Stream。

于 2012-10-17T02:30:00.223 回答
0

有几种方法取决于您希望如何向用户报告反馈。这一切都归结为多线程。

这是一个示例,使用ThreadPool. 请注意,这在整个过程中缺少一堆错误检查......这里是作为如何使用的示例ThreadPool,而不是作为一个健壮的应用程序:

private Dictionary<String, String> _cameras = new Dictionary<String, String> {
    { "http://example.IPcam1.com:81/snapshot.cgi", "/some/path/for/image1.jpg" },
    { "http://example.IPcam2.com:81/snapshot.cgi", "/some/other/path/image2.jpg" },
};

public void DoImageDownload() {
    int finished = 0;

    foreach (KeyValuePair<String, String> pair in _cameras) {
        ThreadPool.QueueUserWorkItem(delegate {
            BeginDownload(pair.Key, pair.Value);
            finished++;
        });
    }

    while (finished < _cameras.Count) {
        Thread.Sleep(1000);  // sleep 1 second
    }
}

private void BeginDownload(String src, String dest) {
    WebRequest req = (WebRequest) WebRequest.Create(src);
    req.Credentials = new NetworkCredential("username", "password");
    WebResponse resp = req.GetResponse();
    Stream input = resp.GetResponseStream();
    using (Stream output = File.Create(dest)) {
        input.CopyTo(output);
    }
}

这个例子只是将你在 for 循环中所做的工作卸载到线程池中进行处理。该DoImageDownload方法将很快返回,因为它没有做太多实际工作。

根据您的用例,您可能需要一种机制来等待图像从DoImageDownload. 一种常见的方法是在BeginDownload下载完成时使用事件回调来通知下载完成。我在while这里放了一个简单的循环,它将等到图像完成......当然,这需要错误检查,以防图像丢失或delegate永远不会返回。

请务必在整个过程中添加错误检查...希望这为您提供了一个开始的地方。

于 2012-10-17T02:25:15.620 回答