Open NuAoA opened 3 years ago
Thanks for the detailed report!
After attempting to clean up some of my test code i'm still running into this exception. It must be some kind of race happening where the previous camera view is closing when the server pushes a command to open the view again.
Looking at the XCT source, it appears it is setup to catch Java.Lang.Exception
and not a generic System.Exception
. That is why this error is crashing the entire application. I am far from a xamarin expert but is there a reason that a System.Exception
should be bubbled up from the camera view and only Java.Lang.Exception
should be caught?
try
{
DisposeMediaRecorder();
}
catch (Java.Lang.Exception e)
{
LogError("Error close device", e);
}
CloseSession();
try
{
if (sessionBuilder != null)
{
sessionBuilder.Dispose();
sessionBuilder = null;
}
if (device != null)
{
device.Close();
device = null;
}
DisposeImageReader();
}
catch (Java.Lang.Exception e)
{
LogError("Error close device", e);
}
I've had some more time to dig into this, and i believe i have confirmed my suspicions that this is a race between threads.
I connected the XCT source to my project to debug things and updated CameraGragment.android.cs
to log the ID of the current thread that is disposing it:
void DisposeImageReader()
{
if (photoReader != null)
{
System.Diagnostics.Debug.WriteLine($"Disposing Image Reader on thread ID {Thread.CurrentThread().Id}");
photoReader.Close();
photoReader.Dispose();
photoReader = null;
}
}
I managed to catch the race happening:
Console Log:
[0:] Disposing Image Reader on thread ID 6191
[0:] Disposing Image Reader on thread ID 2
Exception:
Object reference not set to an instance of an object.
at Xamarin.CommunityToolkit.UI.Views.CameraFragment.DisposeImageReader () [0x0002e] in C:\repos\XamarinCommunityToolkit\src\CommunityToolkit\Xamarin.CommunityToolkit\Views\CameraView\Android\CameraFragment.android.cs:895
at Xamarin.CommunityToolkit.UI.Views.CameraFragment.CloseDevice () [0x0006a] in C:\repos\XamarinCommunityToolkit\src\CommunityToolkit\Xamarin.CommunityToolkit\Views\CameraView\Android\CameraFragment.android.cs:716
at Xamarin.CommunityToolkit.UI.Views.CameraFragment.Android.Views.TextureView.ISurfaceTextureListener.OnSurfaceTextureDestroyed (Android.Graphics.SurfaceTexture surface) [0x00001] in C:\repos\XamarinCommunityToolkit\src\CommunityToolkit\Xamarin.CommunityToolkit\Views\CameraView\Android\CameraFragment.android.cs:799
at Android.Views.TextureView+ISurfaceTextureListenerInvoker.n_OnSurfaceTextureDestroyed_Landroid_graphics_SurfaceTexture_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_surface) [0x00010] in /Users/builder/azdo/_work/2/s/xamarin-android/src/Mono.Android/obj/Release/monoandroid10/android-29/mcw/Android.Views.TextureView.cs:129
at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.84(intptr,intptr,intptr)
When I placed breakpoints to see what is calling into this method there are two sources, when the object is disposed and also the TextureView.ISurfaceTextureListener.OnSurfaceTextureDestroyed
handler.
I think my next steps will be adding a lock around the DisposeImageReader logic to prevent this race condition.
Description
I've run into problems on a android application I am developing where it appears a low level NullReferenceException is being thrown while disposing the camera view from XamarainCommunityToolkit. This exception will crash the whole application and I can't reliably reproduce the issue.
Looking at the source code for this it appears the call is already has a null check, so i'm not sure how the error brings down the application (Xamarin.CommunityToolkit.UI.Views.CameraFragment.DisposeImageReader()). Maybe there is a race condition where the code can pass the null check and another thread has set the value to null?
https://github.com/xamarin/XamarinCommunityToolkit/blob/main/src/CommunityToolkit/Xamarin.CommunityToolkit/Views/CameraView/Android/CameraFragment.android.cs#L890
Stack Trace
Steps to Reproduce
I can't reliably recreate this issue, it appears to happen randomly. I have setup automated testing on my application that will auto navigate through a few screens, acquire a image using the CameraView, navigate back to the landing page and repeat. Once every 100-200 or so cycles the app will hard crash. The stack trace was pulled from logcat.
Basic Information