我有一個應用程序可以即時創建WPF圖像控件以顯示來自SQL Server數據庫表的圖像。顯示控件的面板經常被更換。我使用MemoryStreams來允許控件訪問從數據庫加載的字節數組。只要顯示圖像控件並且仍然顯示圖像,我就無法關閉這些流。我擔心的是,這些流將保持開放狀態,直到垃圾收集器開始處理圖像控件並希望關閉流。我可能會最終確定在更換面板之前關閉了流或丟棄了圖像控件,但是想知道是否存在將這些流打開以及是否存在解決方法的問題。WPF字節數組映射到ImageSource而不使用MemoryStream
下面是我使用的代碼。
public class ImageToSql
{
private static OpenFileDialog _openFileDialog = new OpenFileDialog();
static ImageToSql()
{
_openFileDialog = new OpenFileDialog();
_openFileDialog.AddExtension = true;
_openFileDialog.CheckFileExists = true;
_openFileDialog.DefaultExt = ".jpg";
_openFileDialog.Filter = "JPEG files (*.jpg)|*.jpg|All files (*.*)|*.*";
_openFileDialog.FilterIndex = 1;
_openFileDialog.Multiselect = false;
}
public static BitmapImage LoadImageFromFile(string caption)
{
BitmapImage bi = new BitmapImage();
_openFileDialog.Title = caption;
if (_openFileDialog.ShowDialog() == true)
{
bi.BeginInit();
bi.StreamSource = File.OpenRead(_openFileDialog.FileName);
bi.EndInit();
}
return bi;
}
public static int StoreImage(string connectionString, string sql, string imageParameterName, BitmapImage bitmapImage)
{
SqlConnection conn = new SqlConnection(connectionString);
try
{
conn.Open();
sql += ";SELECT @@IDENTITY";
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
byte[] data = new byte[bitmapImage.StreamSource.Length];
bitmapImage.StreamSource.Seek(0, SeekOrigin.Begin);
bitmapImage.StreamSource.Read(data, 0, data.Length);
cmd.Parameters.Add(imageParameterName, System.Data.SqlDbType.VarBinary, -1).Value = data;
object obj = cmd.ExecuteScalar();
return Int32.Parse(obj.ToString());
}
}
finally
{
conn.Close();
}
}
public static BitmapImage RetrieveImage(string connectionString, string sql, string imageIDParameterName, int imageID)
{
BitmapImage bi = new BitmapImage();
SqlConnection conn = new SqlConnection(connectionString);
try
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.Add(imageIDParameterName, System.Data.SqlDbType.Int).Value = imageID;
byte[] data = (byte[])cmd.ExecuteScalar();
MemoryStream ms = new MemoryStream(data);
ms.Seek(0, SeekOrigin.Begin);
bi.BeginInit();
bi.StreamSource = ms;
bi.EndInit();
}
}
finally
{
conn.Close();
}
return bi;
}
}
下面是如何調用這段代碼。 「_fileImage」和「_sqlImage」是我測試窗口上的圖像控件。有一次,我使用流在「LoadImageFromFile」中從磁盤讀取文件,並認爲我能夠關閉該流,同時仍然在Image控件中顯示圖像。所以,MemoryStream似乎很特別。
BitmapImage bi = ImageToSql.LoadImageFromFile("Select Image to Save");
_fileImage.Source = bi;
int imageID = ImageToSql.StoreImage(connString,
"INSERT INTO PV_Image (Description, Image) VALUES ('Some Image', @pImage)",
"@pImage", bi);
_sqlImage.Source = ImageToSql.RetrieveImage(connString,
"SELECT Image FROM PV_Image WHERE ImageID = @pImageID",
"@pImageID", imageID);
好吧,我可能已經使用了一個「使用」上的SqlConnection自動關閉對我來說。舊習難改。 – 2old4this