从数据库中异步加载图像

时间:2019-01-18 15:35:12

标签: c# wpf asynchronous

到目前为止我在课堂上有什么

  public async Task<BitmapImage> GetBitmap(string ConnectingString, string SQLCode)
    {
        SqlConnection con1 = new SqlConnection(ConnectingString);

        //Open Connection String
        con1.Open();

        // load image from the database 
        SqlCommand Commandcmd = new SqlCommand(SQLCode, con1);
        Task<BitmapImage> t = Task.Run(() =>
        {
            BitmapImage myBitmapImage = new BitmapImage();


            SqlDataReader rdr1 = null;
            rdr1 = Commandcmd.ExecuteReader();


            while (rdr1.Read())
            {
                if (rdr1 != null)
                {
                    if (rdr1[0] != DBNull.Value)
                    {
                        byte[] data = (byte[])rdr1[0]; // 0 is okay if you only selecting one column

                        using (System.IO.MemoryStream ms = new System.IO.MemoryStream(data))
                        {

                            // BitmapImage.UriSource must be in a BeginInit/EndInit block
                            myBitmapImage.BeginInit();
                            myBitmapImage.StreamSource = ms;
                            myBitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                            myBitmapImage.DecodePixelHeight = 500;
                            myBitmapImage.DecodePixelWidth = 500;
                            myBitmapImage.EndInit();
                            myBitmapImage.Freeze();

                        }
                        return myBitmapImage;
                    }


                }

            }

            return myBitmapImage;

        });

        await t;
        return t.Result;
    }

在事件中,我使用的是:

MyImage.Source = await s.GetBitmap(PublicVar.ConnectionString, "SELECT (UserImage) FROM Users WHERE UserID = " + id);

但是当它起作用时,我的程序给我错误 它的文字是 “调用线程无法访问该对象,因为其他线程拥有它。” 我可以通过Dischapter.Invoke进行修复 但这确实不是异步的。 我做错了什么?

2 个答案:

答案 0 :(得分:1)

不要调用Task.Run,而是使用异步ADO.NET方法:

public async Task<BitmapImage> GetBitmap(string ConnectingString, string SQLCode)
{
    SqlConnection con1 = new SqlConnection(ConnectingString);
    //Open Connection String
    await con1.OpenAsync();
    // load image from the database 
    SqlCommand Commandcmd = new SqlCommand(SQLCode, con1);
    BitmapImage myBitmapImage = new BitmapImage();
    SqlDataReader rdr1 = null;
    rdr1 = await Commandcmd.ExecuteReaderAsync();
    while (await rdr1.ReadAsync())
    {
        if (rdr1 != null)
        {
            if (rdr1[0] != DBNull.Value)
            {
                byte[] data = (byte[])rdr1[0]; // 0 is okay if you only selecting one column
                using (System.IO.MemoryStream ms = new System.IO.MemoryStream(data))
                {

                    // BitmapImage.UriSource must be in a BeginInit/EndInit block
                    myBitmapImage.BeginInit();
                    myBitmapImage.StreamSource = ms;
                    myBitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                    myBitmapImage.DecodePixelHeight = 500;
                    myBitmapImage.DecodePixelWidth = 500;
                    myBitmapImage.EndInit();
                    myBitmapImage.Freeze();
                }
                return myBitmapImage;
            }
        }
    }
    return myBitmapImage;
}

Task.Run将在线程池线程上执行指定的操作,您不能从最初在其上创建调度程序线程的其他线程访问UI控件。

答案 1 :(得分:-1)

您甚至可以走得更远,以流的形式读取blob。示例here