调用线程无法访问该对象,因为另一个线程拥有它。如何编辑图像?
我知道有很多此类问题。我想发帖以便分享我的具体问题,因为我感到沮丧。
我正在运行一个线程,该线程从数据库查询路径并将其放入图像元素中。问题是,我在 xaml 中创建了图像,因此当我运行此线程时,它会抛出无法访问此对象错误,即无法访问图像元素。
那么我如何在不使用xaml的情况下设置它?这是我的代码片段:
public partial class Window1 : Window
{
Thread Frame1;
public Window1()
{
InitializeComponent();
intializeDb();
#region start frame 1 thread
Frame1 = new Thread(frame1);
Frame1.SetApartmentState(ApartmentState.STA);
Frame1.IsBackground = true;
Frame1.Start();
#endregion
}
public void frame1()
{
string k;
command.CommandText = "SELECT * FROM imageframe1";
sqlConn.Open();
Reader = command.ExecuteReader();
while (Reader.Read())
{
BitmapImage logo = new BitmapImage();
logo.BeginInit();
k = (string)(Reader.GetValue(1));
logo.UriSource = new Uri(k);
logo.EndInit();
image1.Source = logo; //THROWS THE ERROR HERE.IT CANT ACCESS image1
Thread.Sleep(1000);
}
sqlConn.Close();
Reader.Close();
}
那么我如何访问image1
?如果我在线程中创建一个新的面板,我将不得不将其作为面板的子面板,然后我会收到一个无法访问面板的错误。
有什么办法解决这个问题吗?如果有人可以根据我的代码片段编写一个示例,我很高兴。
编辑仍然没有成功并产生相同的错误:
public partial class Window1 : Window
{
public readonly SynchronizationContext mySynchronizationContext;
public Window1()
{
InitializeComponent();
mySynchronizationContext = SynchronizationContext.Current;
Frame1 = new Thread(frame1);
Frame1.SetApartmentState(ApartmentState.STA);
Frame1.IsBackground = true;
Frame1.Start();
}
public void frame1()
{
string k;
command.CommandText = "SELECT * FROM imageframe1";
sqlConn.Open();
Reader = command.ExecuteReader();
while (Reader.Read())
{
BitmapImage logo = new BitmapImage();
logo.BeginInit();
k = (string)(Reader.GetValue(1));
logo.UriSource = new Uri(k);
logo.EndInit();
SendOrPostCallback callback = _ =>
{
image1.Source = logo;
};
mySynchronizationContext.Send(callback, null);
//image1.Source = logo;
Thread.Sleep(1000);
}
sqlConn.Close();
Reader.Close();
}
}
i know there's a lot of these type of questions. i wanted to post so that i can share my specific prob because im getting frustrated.
im running a thread which query path from db and put it in the image element.problem is, i created the image in xaml so when i run this thread it throws the cannot access this object error which it cant access the image element.
then how do i set it without using xaml??here's my code snippet:
public partial class Window1 : Window
{
Thread Frame1;
public Window1()
{
InitializeComponent();
intializeDb();
#region start frame 1 thread
Frame1 = new Thread(frame1);
Frame1.SetApartmentState(ApartmentState.STA);
Frame1.IsBackground = true;
Frame1.Start();
#endregion
}
public void frame1()
{
string k;
command.CommandText = "SELECT * FROM imageframe1";
sqlConn.Open();
Reader = command.ExecuteReader();
while (Reader.Read())
{
BitmapImage logo = new BitmapImage();
logo.BeginInit();
k = (string)(Reader.GetValue(1));
logo.UriSource = new Uri(k);
logo.EndInit();
image1.Source = logo; //THROWS THE ERROR HERE.IT CANT ACCESS image1
Thread.Sleep(1000);
}
sqlConn.Close();
Reader.Close();
}
how would i access image1
then? if i create a new one within the thread,i will have to put as child of a panel,an then im gonna get an error which it cant access the panel.
any way around this?glad if someone can write an example based on my snippet.
edited with still no success and producing the same error:
public partial class Window1 : Window
{
public readonly SynchronizationContext mySynchronizationContext;
public Window1()
{
InitializeComponent();
mySynchronizationContext = SynchronizationContext.Current;
Frame1 = new Thread(frame1);
Frame1.SetApartmentState(ApartmentState.STA);
Frame1.IsBackground = true;
Frame1.Start();
}
public void frame1()
{
string k;
command.CommandText = "SELECT * FROM imageframe1";
sqlConn.Open();
Reader = command.ExecuteReader();
while (Reader.Read())
{
BitmapImage logo = new BitmapImage();
logo.BeginInit();
k = (string)(Reader.GetValue(1));
logo.UriSource = new Uri(k);
logo.EndInit();
SendOrPostCallback callback = _ =>
{
image1.Source = logo;
};
mySynchronizationContext.Send(callback, null);
//image1.Source = logo;
Thread.Sleep(1000);
}
sqlConn.Close();
Reader.Close();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
正如 Jon Skeet 所说,您可以使用 Dispatcher.Invoke 来分配图像,但这还不够,因为 BitmapImage 已在另一个线程上创建。为了能够在 UI 线程上使用它,您需要先
Freeze
它:As Jon Skeet said, you can use
Dispatcher.Invoke
to assign the image, but it's not enough, because theBitmapImage
has been created on another thread. To be able to use it on the UI thread, you need toFreeze
it before:您使用
Dispatcher
与您想要更新的控件关联:请注意,像这样使用 Thread.Sleep 来执行动画不太可能提供非常好的体验...特别是当显示线程必须获取用于显示图像的 URI。事情不会很顺利。
You use the
Dispatcher
associated with the control you want to update:Note that using
Thread.Sleep
like this to perform animation is unlikely to give a very good experience... especially as the display thread then has to fetch the URI in order to display the image. It's not going to be very smooth.我认为这是因为您没有将调用编组到 UI 线程。您可以执行以下操作:
将上下文保存在构造函数中,
顺便说一句,将 using 语句与
SqlConnection
和SqlDataReader
一起使用是一个很好的做法。如:i think this is because you didnt marshal the call to the UI thread. you can do something line this:
save the context in the constructor,
by the way, its a good practice to use using statements with the
SqlConnection
andSqlDataReader
. as in: