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

Psy*_*ryo 2 c# wpf xaml multithreading 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();

    }
Run Code Online (Sandbox Code Playgroud)

我怎么访问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();

    }
}
Run Code Online (Sandbox Code Playgroud)

Tho*_*que 14

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

logo.Freeze();
Action action = delegate { image1.Source = logo; };
image1.Dispatcher.Invoke(action);
Run Code Online (Sandbox Code Playgroud)