1

我正在开发一个表单上有两个按钮的程序。第一个执行访问数据库的功能,而其他从数据库下载图像并将其与 3 个图像副本(缩略图、缩放、小)一起保存。

访问数据库的代码

using (SqlConnection connection = new SqlConnection(connectionstring))
        {
            connection.Open();
            using (SqlCommand cm = new SqlCommand("query", connection))
            {
                t1.Load(cm.ExecuteReader());
                foreach (DataRow row in t1.Rows)
                {
                    fileNames.Add(row["Filename"].ToString());

                }
            }
         }

访问数据库后,下一个任务是下载图像,生成它的三个副本并将所有内容保存在一个文件夹中。为此,我正在尝试使用BlockingConnection<>. 生产者部分执行下载原始图像并保存的功能,而消费者部分执行访问生产者队列以获取图像然后生成副本的功能。

实现 BlockingCollection 的代码

string baseUrl = "http://some path";


        HttpWebRequest request = null;
        using(BlockingCollection<Image> bc= new BlockingCollection<Image>(20))
        {
        using (Task task1 = Task.Factory.StartNew(() =>
        {
            foreach(var fileName in fileNames)
            {
                string url = string.Format(baseUrl, fileName);
                request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "GET";
                request.ContentType = "application/x-www-form-urlencoded";
                request.CookieContainer = container;

                response = (HttpWebResponse)request.GetResponse();
                Stream stream = response.GetResponseStream();
                img = Image.FromStream(stream);

                bc.Add(img);

                Thread.Sleep(100);

            }
         }))
                    {
                        using (Task task2 = Task.Factory.StartNew(() =>
                            {
                                foreach (var fileName in fileNames)
                                {
                                    foreach (var item in bc.GetConsumingEnumerable())
                                    {
                                     img.Save("C:\\some path" + FileName);
                                    //code to generate copies of images
                                    }
                                }

                            }))
                            Task.WaitAll(task1, task2);

                    }
                   }
        }

让我告诉你,当我用 BackgroundWorker 测试这段代码时,它运行得非常好。我收到错误的部分是尝试将图像保存在 Task1 中的行。

img.Save("C:\\some path" + FileName);

它抛出了这个异常

"An unhandled exception of type 'System.Runtime.InteropServices.ExternalException' occurred in System.Drawing.dll

Additional information: A generic error occurred in GDI+."

我想通了为什么它不保存图像。我已经相应地更改了代码。但它没有正确循环。在获得一个图像并生成其多个副本后,它应该返回第一个 foreach,下载新图像并生成其副本。

4

2 回答 2

0

这可能不是您的问题,但我建议您使用以下代码:

img.Save(System.IO.Path.Combine("C:\\some path",FileName));

而不仅仅是串联。这样可以避免许多错误。

于 2014-04-01T17:20:59.070 回答
0

对于可能遇到类似问题的未来读者,这里是如何修改代码以达到解决方案。希望能帮助到你。

string baseUrl = "http://some url";

        HttpWebRequest request = null;
        using(BlockingCollection<object> bc= new BlockingCollection<object>(20))
        {
        using (Task task1 = Task.Factory.StartNew(() =>
        {

            using (SqlConnection connection = new SqlConnection("connectionstring"))
            {
            connection.Open();
            using (SqlCommand cm = new SqlCommand("query", connection))
            {
                t1.Load(cm.ExecuteReader());
                foreach (DataRow row in t1.Rows)
                {
                     fileNames.Add(row["Filename"].ToString());
                     bc.Add(row["Filename"]);
                }

                Thread.Sleep(100);
                Console.WriteLine("This is Add part");
            }

            }
            bc.CompleteAdding();
         }))
                    {
                        using (Task task2 = Task.Factory.StartNew(() =>
                            {
                                    foreach (var item in bc.GetConsumingEnumerable())
                                    {
                                    string url = string.Format(baseUrl, item);
                                    request = (HttpWebRequest)WebRequest.Create(url);
                                    request.Method = "GET";
                                    request.ContentType = "application/x-www-form-urlencoded";
                                    request.CookieContainer = container;

                                    response = (HttpWebResponse)request.GetResponse();
                                    Stream stream = response.GetResponseStream();
                                    img = Image.FromStream(stream);
                                    img.Save("C:\\some path" + item);
                                    //code to create copies of image.

                                    }
                                    Console.WriteLine("This is Take part");

                            }))
                                    Task.WaitAll(task1,task2);

                    }

                   }
        }
于 2014-04-02T14:00:15.650 回答