我正在开发一个表单上有两个按钮的程序。第一个执行访问数据库的功能,而其他从数据库下载图像并将其与 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,下载新图像并生成其副本。