0

The calling thread cannot access this object because a different thread owns it.

The exception message stated above occurs generally when UI controls are accessed by other threads rather than the UI thread itself.I came through this issue.As far my experience,i faced this error while i tried to access the UI from a BackGroundWorker's DoWork event.When i became aware of the fact that the UI cannot be accessed from a different thread rather than the UI thread,i switched to other methods to tackle such a situation by doing some HEAVY NON-UI work in DoWork event.Today,i thought of doing something different(which may be not different to u as u may have done this before).I tried to do the UI THINGS in DoWork event in a very different way.

Before i post my huge code,excuse me to explain a bit please.

My motive was to load a few images in some Image control from a database/datatable in WPF.This takes some time as there are more than just a few images in the database/datatable.It results in UI-Freeze.So i though if declaring a Class level List(of BitmapImage) variable,add images to that and then , in RunWorkerCompleted event,i thought of doing a For Each loop and load images in Image controls.

Before i would test it, i tried implementing this using a database with single image and only a single Image control.

Here's how i add images:

public class TestSub
{
BitmapImage CurrentUserPhoto = new BitmapImage;
private void LoadAccounts_DoWork(object sender, DoWorkEventArgs e)
{
    con.Open();
    OleDbCommand cmd2 = new OleDbCommand("Select * from userinfo where   Email='" + currentemail + "'", con);
    byte[] photo;
    OleDbDataReader dr2 = cmd2.ExecuteReader;
    while (dr2.Read)
    {
        try
        {
            photo = (byte[])dr2(11);
            MemoryStream strm = new MemoryStream(photo);
            BitmapImage bi = new BitmapImage;
            bi.BeginInit();
            bi.CacheOption = BitmapCacheOption.OnLoad;
            bi.StreamSource = strm;
            bi.EndInit();
            CurrentUserPhoto = bi;
        }
        catch (Exception ex)
        {
        }

        if (dr2(9).ToString == "")
        {
        }
        else
        {
            CurrentUser = dr2(9);
        }
    }

    con.Close();
}
}

Then,in RunWorkerCompleted, i try to load that image :

 private void LoadCurrentAccount_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    CurrentUserPhoto.BeginInit();
    userpic.ImageSource = CurrentUserPhoto;
    CurrentUserPhoto.EndInit();
    CurrentUserName.Content = CurrentUser;
}

BAMMM!The error occurs!! In the first line CurrentUserPhoto.BeginInit(); . I am not getting it as i am(as far my knowledge) not tying to access the UI from a different thread(i mean,i ain't accessing it from DoWordk event).

So,can somebody please explain to me why this error is occuring ?

  • The content in `CurrentUserPhoto` is still created in a background thread. The place of assignments is less important. – Peter Bons Mar 04 '18 at 17:50
  • what to do then ? –  Mar 04 '18 at 17:52
  • Get the byte array in the background and create the image itself in the completed event. – Peter Bons Mar 04 '18 at 17:53
  • 3
    No, don't do that! Just call `bi.Freeze()` after EndInit to make it cross-thread accessible. And as a general rule, close the MemoryStream by a using block `using (var str = new MemoryStream(photo)) { ... }` – Clemens Mar 04 '18 at 17:57
  • 1
    @Clemens ah, didn't know. Thanks, learnt something new today! – Peter Bons Mar 04 '18 at 17:58
  • i will try but @PeterBons, can u explain a bit –  Mar 04 '18 at 17:58
  • @Clemens,it now throws `Specified value of type 'System.Windows.Media.Imaging.BitmapImage' must have IsFrozen set to false to modify` –  Mar 04 '18 at 18:39
  • Sure, after freezing it can't be modified. No idea what you're doing though... However, `CurrentUserPhoto.BeginInit()` and `CurrentUserPhoto.EndInit()` in RunWorkerCompleted don't seem to make much sense. – Clemens Mar 04 '18 at 19:05
  • @clemens,i tried to add the bitmap from `DoWork` to `currentUserPhoto` and wanted to uses as the imagesource of `UserPic`, and i know that `beginInIt` and `EndInIt` is useless in `RunWorkerCompleted` event but if i remove 'em , i get an error which suggests to add them...any help with that ? –  Mar 04 '18 at 19:40
  • @Clemens,thank u sooo much!! I understood and solved my problem. –  Mar 04 '18 at 20:47

0 Answers0