c# - 调用线程无法访问此对象,因为另一个线程拥有它。如何编辑图像?

标签 c# wpf multithreading xaml accessibility

我知道有很多此类问题。我想发帖以便分享我的具体问题,因为我感到很沮丧。

我正在运行一个从 db 查询路径并将其放入图像元素的线程。问题是,我在 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();

    }
}

最佳答案

正如 Jon Skeet 所说,您可以使用 Dispatcher.Invoke 来分配图像,但这还不够,因为 BitmapImage 已在另一个线程上创建。为了能够在 UI 线程上使用它,您需要先卡住它:

logo.Freeze();
Action action = delegate { image1.Source = logo; };
image1.Dispatcher.Invoke(action);

关于c# - 调用线程无法访问此对象,因为另一个线程拥有它。如何编辑图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5961179/

相关文章:

c# - 尝试在 Visual Studio 2008 中编辑 UI 时出现 WPF Designer 异常

c# - 使用 XAML 在 WPF 中设置进度条样式

java线程同步问题,如何实现observable线程

c# - 我的 ASP.Net TextBox 有一个自动生成的名称,这意味着我无法在客户端脚本中使用它...如何同时使用服务器和客户端代码?

c# - NLog MappedDiagnosticsLogicalContext 不工作在异步/等待与 ConfigureAwait(false)

c# - WPF 在触发器上更改 Grid.ColumnSpan

multithreading - 为什么要设置线程的Terminal属性?

java.lang.OutOfMemoryError : unable to create new native thread ..在Windows中重新创建

C# 表单问题

c# - 使用 DataTemplate 将 View 绑定(bind)到 ViewModel 时出现问题