如何同时从相同的代码执行多任务处理?

时间:2012-10-17 02:19:30

标签: c# visual-studio-2010 webforms

对不起,如果标题不清楚或不正确,不知道我应该放什么标题。如果错误请纠正 我有这个代码从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);
   }
}

2 个答案:

答案 0 :(得分:3)

您不应该从ASP.NET应用程序中运行长时间运行的代码。它们只是为了回应请求。

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

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

答案 1 :(得分: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永远不会返回。

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