sabitertan / BlazorBarcodeScanner

Barcode Scanner component for Blazor using zxing-js Interop
MIT License
92 stars 37 forks source link

Error with BarcodeReader when StartCameraAutomatically is true #51

Closed vangelkolarov-actioncamvideo closed 1 year ago

vangelkolarov-actioncamvideo commented 1 year ago

Setup: NET 7, Blazor Server-side (use the project BarcodeReaderIssue.zip)

Steps to reproduce:

  1. Refresh the page with reload button or press F5
  2. Scan a QR code

Expected results: No error should occur on receiving barcode text

Actual results: An error occurs on StateHasChanged() at the callback function: The current thread is not associated with the Dispatcher. (see the video https://user-images.githubusercontent.com/76152571/218969612-6a2f57c3-0587-4134-b1d5-e61e178ce117.mp4)

shannonslaton commented 1 year ago

Are you able to get a barcode to read? I am only able to get a QR Code to read.

vangelkolarov-actioncamvideo commented 1 year ago

Are you able to get a barcode to read? I am only able to get a QR Code to read.

Yes, I get the QR code but then it throws an exception on the StateHasChanged() call.

shannonslaton commented 1 year ago

I get that, but are you able to read barcodes? I can only read QR codes. Barcodes don't seem to trigger anything.

vangelkolarov-actioncamvideo commented 1 year ago

I'm using the tool to read only QR codes, no barcodes.

shannonslaton commented 1 year ago

Ok. Well, I am not having your issue. It seems to work just fine for me with scanning QR codes and the camera turning on automatically. Maybe it's a camera/driver issue? Any chance you could test to see if you can read a barcode and let me know if it works for you?

vangelkolarov-actioncamvideo commented 1 year ago

I tested with a barcode and I got the same error. I don't think is a camera issue because I hosted the website publicly (https://barcodereaderissue.azurewebsites.net/) and I tested with the camera on my smartphone, and I have the same problem. I think initially the issue is coming after the page is reloaded and I have the following exception:

System.NullReferenceException: Object reference not set to an instance of an object. at BlazorBarcodeScanner.ZXing.JS.BarcodeReader.StopDecoding() at BlazorBarcodeScanner.ZXing.JS.BarcodeReader.Dispose() at Microsoft.AspNetCore.Components.RenderTree.Renderer.Dispose(Boolean disposing) --- End of stack trace from previous location --- at Microsoft.AspNetCore.Components.RenderTree.Renderer.Dispose(Boolean disposing) at Microsoft.AspNetCore.Components.Rendering.RendererSynchronizationContext.<>c.b8_0(Object state) --- End of stack trace from previous location --- at Microsoft.AspNetCore.Components.RenderTree.Renderer.DisposeAsync() at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.g__Await|22_0(Int32 i, ValueTask vt, List`1 toDispose) at Microsoft.AspNetCore.Http.Features.RequestServicesFeature.gAwaited|9_0(RequestServicesFeature servicesFeature, ValueTask vt) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.g__ProcessEvents|242_0(HttpProtocol protocol, Stack`1 events)

diegorod commented 1 year ago

Tested your code with a webcam and it worked fine with qr codes.

vangelkolarov-actioncamvideo commented 1 year ago

Did you reload the page before scanning? Do you see any error in the Visual Studio Output window after the reload?

diegorod commented 1 year ago

Probably shouldn't be calling StateHasChanged() while Disposing which is currently being done via StopDecoding() Ref

        public void Dispose()
        {
            StopDecoding();
        }
...
...
...
        public void StopDecoding()
        {
            BarcodeReaderInterop.OnBarcodeReceived(string.Empty);
            _backend?.StopDecoding();
            IsDecoding = false;
            StateHasChanged();
        }
vangelkolarov-actioncamvideo commented 1 year ago

Hi @diegorod , thank you for your comment. Yes, the issue is calling StateHasChanged() while disposing and I think this should be fixed in the next version.

Now I realized that we have a similar error on calling await OnBarcodeReceived.InvokeAsync(args) at method ReceivedErrorMessage(ErrorReceivedEventArgs args):

System.InvalidOperationException: The current thread is not associated with the Dispatcher. Use InvokeAsync() to switch execution to the Dispatcher when triggering rendering or component state. at Microsoft.AspNetCore.Components.Dispatcher.AssertAccess() at Microsoft.AspNetCore.Components.RenderTree.Renderer.AddToRenderQueue(Int32 componentId, RenderFragment renderFragment) at Microsoft.AspNetCore.Components.ComponentBase.StateHasChanged() at Microsoft.AspNetCore.Components.ComponentBase.Microsoft.AspNetCore.Components.IHandleEvent.HandleEventAsync(EventCallbackWorkItem callback, Object arg) at BlazorBarcodeScanner.ZXing.JS.BarcodeReader.ReceivedBarcodeText(BarcodeReceivedEventArgs args) at System.Threading.Tasks.Task.<>c.b__128_0(Object state) at Microsoft.AspNetCore.Components.Rendering.RendererSynchronizationContext.ExecuteSynchronously(TaskCompletionSource completion, SendOrPostCallback d, Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) --- End of stack trace from previous location --- at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) at Microsoft.AspNetCore.Components.Rendering.RendererSynchronizationContext.ExecuteBackground(WorkItem item)

And I'm not quite sure if this is only a local issue.

sabitertan commented 1 year ago

This is more of a JS interop problem use this instead to avoid that :

 private async Task LocalReceivedBarcodeText(BarcodeReceivedEventArgs args)
        {
            await InvokeAsync(() => {
                this.LocalBarcodeText = args.BarcodeText;
                StateHasChanged();
            });
        }