Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

System.ObjectDisposedException: 'Cannot access a closed Stream on .net 8 maui android #19230

Open
Eves101 opened this issue Dec 5, 2023 · 23 comments
Labels
area-controls-image Image control platform/android 🤖 s/triaged Issue has been reviewed s/verified Verified / Reproducible Issue ready for Engineering Triage t/bug Something isn't working
Milestone

Comments

@Eves101
Copy link

Eves101 commented Dec 5, 2023

Description

When images are loaded from a memorystream on to a page, when going back via the backbutton on an android device a fatal error occurs. But not always, but often.

Please try the project in the repository, It is based on @jfversluis MauiBase64ImageSample on git.

Steps to Reproduce

  1. Create a new maui navigationpage app
  2. create a contentview that holds the image
  3. create a contentpage that holds several views with image
  4. create several pages from the mainpage
  5. use the backbutton to close the pages
  6. observe the error

Link to public reproduction project repository

MauiBase64ImageStreamTest

Version with bug

8.0.3

Is this a regression from previous behavior?

Not sure, did not test other versions

Last version that worked well

Unknown/Other

Affected platforms

Android, Windows

Affected platform versions

No response

Did you find any workaround?

Cache the files, see project inthe repository

Relevant log output

**System.ObjectDisposedException:** 'Cannot access a closed Stream.'

[mono-rt] [ERROR] FATAL UNHANDLED EXCEPTION: System.ObjectDisposedException: Cannot access a closed Stream.
[mono-rt]    at System.IO.MemoryStream.EnsureNotClosed()
[mono-rt]    at System.IO.MemoryStream.Read(Byte[] buffer, Int32 offset, Int32 count)
[mono-rt]    at Android.Runtime.InputStreamAdapter.Read(Byte[] bytes, Int32 offset, Int32 length) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/InputStreamAdapter.cs:line 38
[mono-rt]    at Java.IO.InputStream.n_Read_arrayBII(IntPtr jnienv, IntPtr native__this, IntPtr native_b, Int32 off, Int32 len) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/obj/Release/net7.0/android-33/mcw/Java.IO.InputStream.cs:line 264
[mono-rt]    at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PPLII_I(_JniMarshal_PPLII_I callback, IntPtr jnienv, IntPtr klazz, IntPtr p0, Int32 p1, Int32 p2) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.cs:line 264
[HostConnection] createUnique: call
[HostConnection] HostConnection::get() New Host Connection established 0x7c0ff54aff50, tid 31493
[HostConnection] HostComposition ext ANDROID_EMU_CHECKSUM_HELPER_v1 ANDROID_EMU_native_sync_v2 ANDROID_EMU_native_sync_v3 ANDROID_EMU_native_sync_v4 ANDROID_EMU_dma_v1 ANDROID_EMU_direct_mem ANDROID_EMU_host_composition_v1 ANDROID_EMU_host_composition_v2 ANDROID_EMU_vulkan ANDROID_EMU_deferred_vulkan_commands ANDROID_EMU_vulkan_null_optional_strings ANDROID_EMU_vulkan_create_resources_with_requirements ANDROID_EMU_YUV_Cache ANDROID_EMU_vulkan_ignored_handles ANDROID_EMU_has_shared_slots_host_memory_allocator ANDROID_EMU_vulkan_free_memory_sync ANDROID_EMU_vulkan_shader_float16_int8 ANDROID_EMU_vulkan_async_queue_submit ANDROID_EMU_vulkan_queue_submit_with_commands ANDROID_EMU_sync_buffer_data ANDROID_EMU_vulkan_async_qsri ANDROID_EMU_read_color_buffer_dma GL_OES_EGL_image_external_essl3 GL_OES_vertex_array_object GL_KHR_texture_compression_astc_ldr ANDROID_EMU_host_side_tracing ANDROID_EMU_gles_max_version_3_0
@Eves101 Eves101 added the t/bug Something isn't working label Dec 5, 2023
@ghost ghost added the legacy-area-controls Label, Button, CheckBox, Slider, Stepper, Switch, Picker, Entry, Editor label Dec 5, 2023
@PureWeen PureWeen added this to the Backlog milestone Dec 5, 2023
@ghost
Copy link

ghost commented Dec 5, 2023

We've added this issue to our backlog, and we will work to address it as time and resources allow. If you have any additional information or questions about this issue, please leave a comment. For additional info about issue management, please read our Triage Process.

@Eves101
Copy link
Author

Eves101 commented Dec 7, 2023

Upgraded the github project to .net 8

@Eves101
Copy link
Author

Eves101 commented Dec 7, 2023

Windows machine also crashes on 10 pages or more in the sample project.
Workaround added in the repo: caching files and using the filenames is working.

@XamlTest XamlTest added s/verified Verified / Reproducible Issue ready for Engineering Triage s/triaged Issue has been reviewed labels Jan 9, 2024
@XamlTest
Copy link

XamlTest commented Jan 9, 2024

Verified this on Visual Studio Enterprise 17.9.0 Preview 2(8.0.3). Repro on Android 14.0-API34 and Windows 11 with below Project:
MauiBase64ImageSample.zip

@dupuisdavid
Copy link

@TarikSaibi

@SamJealTe
Copy link

We are having the same issue. After I load the image from memory stream and open a new page and navigate to back, I receive System.ObjectDisposedException on Android. This issue is preventing us to go live. When will we have a fix for this?

@r-work
Copy link

r-work commented Feb 19, 2024

Same issue here, why is this added to the backlog? is there at least some sort of workaround?

@Eves101
Copy link
Author

Eves101 commented Feb 19, 2024

I work around it by clearing the android imagecache:

var imageManagerDiskCache = Path.Combine(FileSystem.CacheDirectory, "image_manager_disk_cache");

                if (Directory.Exists(imageManagerDiskCache))
                {
                    foreach (var imageCacheFile in Directory.EnumerateFiles(imageManagerDiskCache))
                    {
                        File.Delete(imageCacheFile);
                    }
                }

@r-work
Copy link

r-work commented Feb 19, 2024

@Eves101 thanks for the snippet, how often do you run this? do you use a timer or something?

@Eves101
Copy link
Author

Eves101 commented Feb 19, 2024

I call it when i cache or delete a file, soo fairly often... :(

@naaeef
Copy link

naaeef commented Feb 22, 2024

Hi @Eves101
Do you have a sample on how to apply your workaround?

@r-work
Copy link

r-work commented Feb 22, 2024

Not exactly sure either, I do not cache any images, mine usually loads from from a local SQLITE db, or just in memory, like a user avatar.

@Eves101
Copy link
Author

Eves101 commented Feb 23, 2024

@naaeef
I take this approach:

  • get an image from api in a stream
  • empty the android cache
  • save the image to the app data folder/yourfoldername/ ( with a filename like: avatar.jpg)
  • assign the filename to the imagesource

@SamJealTe
Copy link

SamJealTe commented Mar 20, 2024

I don't get how this issue hasn't been fixed for 4 months. Saving the image may sound as workaround but it is basically a whole different approach people use to avoid this issue.

@Eilon Eilon removed the legacy-area-controls Label, Button, CheckBox, Slider, Stepper, Switch, Picker, Entry, Editor label May 10, 2024
@samhouts samhouts added s/verified Verified / Reproducible Issue ready for Engineering Triage s/triaged Issue has been reviewed and removed s/verified Verified / Reproducible Issue ready for Engineering Triage s/triaged Issue has been reviewed labels Jul 3, 2024
@PureWeen
Copy link
Member

PureWeen commented Sep 7, 2024

@jonathanpeppers thoughts?

@jonathanpeppers
Copy link
Member

jonathanpeppers commented Sep 9, 2024

This feels like "MAUI doesn't handle cancellation", right?

Looking at the code:

PlatformInterop.LoadImageFromStream(imageView, stream, callback);
var result = await callback.Result;
stream?.Dispose();

If you navigated away from the page, I don't see what would cancel this gracefully.

Can someone comment what method in the sample is the problematic one? Which one of these?

@LeoJHarris
Copy link

LeoJHarris commented Sep 19, 2024

👀 seems to happen when scrolling back up on CollectionView after scrolling down through items when items have ImageSource value set i.e. ImageSource.FromStream(() => copyStream)

The offending code seems to be:

MemoryStream copyStream = new();
await memoryStream.CopyToAsync(copyStream).ConfigureAwait(true);
copyStream.Position = 0;

viewModels.ImageSource = ImageSource.FromStream(() => copyStream);

@alexanderdibenedetto
Copy link

Also seeing this issue in our production android application. The rate is low but impact is high as the entire Android app crashes as a result of this issue. We do not see this issue on iOS, only on Android.

@bcaceiro
Copy link

bcaceiro commented Oct 4, 2024

Also facing the same issue. CV with images

@SamJealTe
Copy link

We started having this issue after upgrading our app to .net 8 just before giving it to testers. It was working fine with .net 7. Our job was converting an existing production xamarin app to maui. I think it was like 10-11 months ago. This issue was the biggest reason the whole project was cancelled and the maui app didn't go live. I am not exaggerating. It was decided it would take too much effort to keep maintaining maui apps.

@LeoJHarris
Copy link

This is still a big problem, it might as well be on par with #25224 which we also suffer from, for this issue though you cannot scroll down more then 10 items in a CollectionView with images until the app crashes.

@LeoJHarris
Copy link

LeoJHarris commented Nov 3, 2024

App also crashes on simple page navigation. What is the update on this ticket??? This is blocking our ability to release a stable production version.

@LeoJHarris
Copy link

To update everyone we made a slight adjustment with the following change and we dont't seem to get this crash occuring as frequent, if at all now. Someone else can confirm.

  1. Create a Copy of the Stream:
    • A MemoryStream is created to copy the contents of the original stream.
    • The position of the copied stream is reset to the beginning.
  2. Use the Copied Stream:
    • The copied stream is used to create the ImageSource by converting it to a byte array and then creating a new MemoryStream from the byte array.
Stream? imageStream = await fileResult.OpenReadAsync().ConfigureAwait(true);
if (imageStream is not null)
{
    // Create a copy of the stream to avoid disposing issues
    MemoryStream copyStream = new();
    await imageStream.CopyToAsync(copyStream).ConfigureAwait(true);
    copyStream.Position = 0; // Reset position to the beginning

    // Use the copied stream to create the ImageSource
    ImageSource = ImageSource.FromStream(() => new MemoryStream(copyStream.ToArray())); // <=== Include a new MemoryStream
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-controls-image Image control platform/android 🤖 s/triaged Issue has been reviewed s/verified Verified / Reproducible Issue ready for Engineering Triage t/bug Something isn't working
Projects
None yet
Development

No branches or pull requests