0

I try to process a method asynchronously adn store the result in an ObservableCollection, but I always get the Error

Must create DependencySource on same Thread as the DependencyObject.

This is my Default Code that I try to use for the operation: The method LoadServiceTasksAsync is called by a button.

public async void LoadServiceTasksAsync(object o)
    {
        var serviceTasks = await Task.Run(() => repository.GetServiceTasks((string)o)); 
        
        var serviceTasksViewModels =  serviceTasks.Select(m => new ServiceTaskViewModel()
        {
            OSM = m.OSM,
            Priority = "" + m.Priority,
            Status = m.Status
        });
        ServiceTasks = new ObservableCollection<ServiceTaskViewModel>(serviceTasksViewModels);
    }

I also have tried to wrap it in a Dispatcher like this:

public async void LoadServiceTasksAsync(object o)
    {
        var serviceTasks = await Task.Run(() => repository.GetServiceTasks((string)o)); 
        Application.Current.Dispatcher.Invoke(() =>
                {
                    var serviceTasksViewModels =  serviceTasks.Select(m => new ServiceTaskViewModel()
                       {
                       OSM = m.OSM,
                       Priority = "" + m.Priority,
                       Status = m.Status,
                       });
                    ServiceTasks = new ObservableCollection<ServiceTaskViewModel>(serviceTasksViewModels);
               });
    }

I know that I have to create the serviceTaskViewModels in the MainThread but I have no idea how to do that as the serviceTasks are always in another Thread.

EDIT:

var serviceTasks is an IEnumerable<Models.ServiceTask> which are downloaded with a library from a MySQL-Database. The method repository.GetServiceTasks((string)o) itself works fine. So if I execute var serviceTasks = repository.GetServiceTasks((string)o); there are no problems, except the freezing UI.

I also have only one UI Thread.

Maik
  • 42
  • 6

1 Answers1

0

Unfortunately I made a mistake while creating the object 'OSM' as there is a little Bitmap created depending of the state of a value.

The assignment of the Bitmap inside the 'OSM'object causes the exception.

The solution for this is to 'Freeze()' the Bitmaps: async load BitmapImage in C#

In my case it looks like: (Shortened Version)

double? l11 = ERPStockList.getStockLevel(sapc.obj, "680");
        if (l11 != null && l11>l1)
        {
            l1 = (double)ERPStockList.getStockLevel(sapc.obj, "680");
            if (l1 >= sapc.iQuantity) { bl1 = toBitmap(File.ReadAllBytes("GreenDot.png")); }
            else if (l1 > 0) { bl1 = toBitmap(File.ReadAllBytes("OrangeDot.png")); }
            else { bl1 = toBitmap(File.ReadAllBytes("RedDot.png")); 
        }
OSM osm = new OSM()
    {                   
        LO_Acta = bl1,
        LO_Windlift = bl2,
        LO_Onshore = bl3
    };
osm.LO_Acta.Freeze();
osm.LO_Onshore.Freeze();
osm.LO_Windlift.Freeze();
osmList.Add(osm);

The toBitmap-Method:

public BitmapImage toBitmap(Byte[] value)
    {
        if (value != null && value is byte[])
        {
            byte[] ByteArray = value as byte[];
            BitmapImage bmp = new BitmapImage();
            bmp.BeginInit();
            bmp.StreamSource = new MemoryStream(ByteArray);
            bmp.DecodePixelHeight = 10;
            bmp.DecodePixelWidth = 10;
            bmp.EndInit();
            return bmp;
        }
        return null;
    }
Maik
  • 42
  • 6