0

Sorry If this question has already been asked, but I cannot find the solution. I was searching for loading images into listview directly from URL using OberveableCollection that doesn't hang my UI somehow, I got this solution, and it's working great, but I also want to show username along with image; how can I modify the below code to do so.

public void LoadImage(object uri)
    {
        try
        {
            var decoder = new JpegBitmapDecoder(new Uri(uri.ToString()), BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
            decoder.Frames[0].Freeze();
            this.Dispatcher.Invoke(DispatcherPriority.Send, new Action<ImageSource>(SetImage), decoder.Frames[0]);
        }
        catch(Exception ex)
        {
            Debug.WriteLine($"{ex.Message}\n{uri}");
        }
       
    }

    public void SetImage(ImageSource source)
    {
        Debug.WriteLine("Inside set image!");
        LocalMembers local = new LocalMembers(source);
        members.Add(local);
        Debug.WriteLine($"Image has been set {members.Count()}");
    }

Here I'm using ThreadPool to call the function

ThreadPool.QueueUserWorkItem(LoadImage, img);

right now, it's only taking img URL, but i also want to pass other things like username, memberId my class, LocalMembers has three member

private ImageSource imageURL;
    private string username;
    private string id;

any idea how can i modify this function to show other data like username and id also using this threadpool

  • Pack all required data into a class and pass it to the QueueUserWorkItem call – Klaus Gütter Jul 28 '22 at 05:56
  • @KlausGütter anything else to change in loadimage and setimage functions after passing it? – Mian Ismaili Jul 28 '22 at 06:02
  • A note on ThreadPool.QueueUserWorkItem. This has been a valid approach for many years, but today you would prefer to use `async/await`. You would wrap the creation of a BitmapSource in a call like `await Task.Run(() => { ... bitmap = BitmapFrame.Create(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad); ... });`. Note also the use of the more generic `BitmapFrame.Create` method, instead of the very specific use of a JpegBitmapDecoder. See e.g. [this answer](https://stackoverflow.com/a/46709476/1136211) for an example. – Clemens Jul 28 '22 at 07:41
  • @Clemens thanks for the clarification I'll take a look the answer – Mian Ismaili Jul 28 '22 at 07:51
  • The linked answer also covers the (usual) case that a currently downloading bitmap can not be frozen. Your code may only work by accident - or is it only loading local files by URL? – Clemens Jul 28 '22 at 08:03
  • It's loading images from URL and the above threadpool working like a charm and it doesn't hang the UI – Mian Ismaili Jul 28 '22 at 08:08
  • From URL, sure, but are these local file URLs or http URLs for files on a web server? – Clemens Jul 28 '22 at 08:33
  • Ok, I just checked this. It seems that when you explicitly use a JpegBitmapDecoder (or any other of the decoders), instead of using BitmapDecoder.Create or BitmapFrame.Create, the downloaded BitmapFrame is freezable. Not sure however if you can really rely on that. It may happen that the Freeze method throws an exception in case the BitmapFrame is not freezable because it is still downloading. – Clemens Jul 28 '22 at 08:39
  • @Clemens the solution that you provide will solve my problem? – Mian Ismaili Jul 28 '22 at 09:28
  • Not sure what exactly you mean with your "problem". Here you are asking about how to add more data to a data item that is presented in a ListView. I was just adding a note, saying that async/await is a more modern approach than QueueUserWorkItem, and that you should be aware of the fact that the Freeze call may fail. – Clemens Jul 28 '22 at 10:06

0 Answers0