2

I'm using QR Code Scanner in Xamarin App, when it scans the qr code, there are some operation it does which takes about a minute, while it's performing operation, I want to show a loading dialog on the screen. But, it isn't showing on the screen, and elsewhere in the app, it's working perfectly.

Code

var expectedFormat = ZXing.BarcodeFormat.QR_CODE;
var opts = new ZXing.Mobile.MobileBarcodeScanningOptions { PossibleFormats = new List<ZXing.BarcodeFormat> { expectedFormat } };
var scanner = new ZXing.Mobile.MobileBarcodeScanner();
var result = await scanner.Scan(opts);
if (result == null)
{
    // code

    return null;
}
else
{
    using (UserDialogs.Instance.Loading("Processing"))
    {
        // code
    }
}

UPDATE CODE SAMPLE

public async Task Verification(object sender, EventArgs e)
{
    try
    {
        var expectedFormat = ZXing.BarcodeFormat.QR_CODE;
        var opts = new ZXing.Mobile.MobileBarcodeScanningOptions { PossibleFormats = new List<ZXing.BarcodeFormat> { expectedFormat } };
        var scanner = new ZXing.Mobile.MobileBarcodeScanner();
        var result = await scanner.Scan(opts);
        if (result == null)
        {
            // Code
            
            return null;
        }
        else
        {
            try
            {
                // QR Scan Result
                string qr_scan = result.Response;

                var result = JsonConvert.DeserializeObject<QRScan>(qr_scan);

                await CreateConnection();
            }
            catch (Exception error)
            { }
            finally
            {
                // navigate to next page
                await NavigationService.NavigateToAsync<NextViewModel>();
            }
        }
    }
    catch (Exception error)
    { }

    return null;
}

public async Task CreateConnection()
{
    UserDialogs.Instance.Loading("Processing");
     
    if ()
    {
        try
        {
            // Code
        }
        catch (Exception error)
        {
            // Code
        }
        finally
        {
            await CreateFolder(default, default);
        }
    }
}

public async Task CreateFolder(object sender, EventArgs e)
{
    UserDialogs.Instance.Loading("Processing");

    try
    {
        // Code
    }
    catch (Exception error)
    {
        // Code
    }

    return null;
}  
Stavrogin
  • 135
  • 1
  • 15
  • Did you try to do it in the mainthread like `Device.BeginInvokeOnMainThread(()=> { UserDialogs.Instance.Loading("Processing"); });` – Leo Zhu May 06 '21 at 02:34
  • nah, it didn't work and it also **navigated** to the next page before the code inside `Device.BeginInvokeOnMainThread()` get executed. – Stavrogin May 06 '21 at 04:52
  • Don't wrap it with using – Leo Zhu May 06 '21 at 05:18
  • I've actually multiple functions like `else { if () { newfunction(); } else { newfunction(); } }`, and then in `newfunction()`, it goes to another function, like this... – Stavrogin May 06 '21 at 05:24
  • @LeoZhu-MSFT same issue, navigate to the next page before the code inside `Device.BeginInvokeOnMainThread()` get executed... – Stavrogin May 06 '21 at 06:37
  • `Device.BeginInvokeOnMainThread(async () => { UserDialogs.Instance.Loading("Processing"); // Code }` – Stavrogin May 06 '21 at 06:38
  • Could you share a simple sample,then i could test it. – Leo Zhu May 06 '21 at 08:46
  • I added the structure of the code, sorry isn't possible to paste the code here.. – Stavrogin May 06 '21 at 10:47

2 Answers2

2

Try something like this

Device.BeginInvokeOnMainThread(async () =>
{

    try
    {
        using (UserDialogs.Instance.Loading(("Processing")))
        {
            await Task.Delay(300);
                      
            //Your Service code
        }
    }
    catch (Exception ex)
    {
        var val = ex.Message;
        UserDialogs.Instance.Alert("Test", val.ToString(), "Ok");
    }
});
Judson Abraham
  • 316
  • 2
  • 11
  • 37
2

You can use Xamarin.Essentials' MainThread class and more specifically - the InvokeOnMainThreadAsync method. The idea of this method is to not only execute a code on the UI/main thread, but to also to await it's code. This way you can have both async/await logic and main thread execution.

try
{
    // QR Scan Result
    string qr_scan = result.Response;
    var result = JsonConvert.DeserializeObject<QRScan>(qr_scan);
    await MainThread.InvokeOnMainThreadAsync(() => CreateConnection());
}
catch (Exception error)
{ }
finally
{
    // navigate to next page
    await NavigationService.NavigateToAsync<NextViewModel>();
}

Keep in mind that if the method CreateConnection takes a long time to execute, then it would be better to execute on the main thread only the dialog presentation (UserDialogs.Instance.Loading("")).

Brandon Minnick
  • 13,342
  • 15
  • 65
  • 123
Mihail Duchev
  • 4,691
  • 10
  • 25
  • 32
  • I'm very sorry for responding late.. actually, it didn't worked.. I used `await MainThread.InvokeOnMainThreadAsync(() => CreateConnection());` and `await MainThread.InvokeOnMainThreadAsync(() => UserDialogs.Instance.Loading("Processing"));`.. but none of the code made any change in the UI – Stavrogin May 15 '21 at 12:19
  • Can you try to invoke a native dialog via `await DisplayAlert ("Alert", "You have been alerted", "OK");` in the `InvokeOnMainThreadAsync` Action, just to see if the rest of the code will be executed while the dialog is opened? The code should execute only after the async dialog method has been finished (after the dialog has been closed)? – Mihail Duchev May 15 '21 at 15:44
  • When I scan QR Code, for a half second it shows the qr code and then come back to the page where I click on "Scan QR Code" button.. and it isn't navigating to next page (the rest of the code isn't executing).. – Stavrogin May 16 '21 at 13:54
  • I tried both `await MainThread.InvokeOnMainThreadAsync(() => DisplayAlert ("Alert", "You have been alerted", "OK"));` and `await Device.InvokeOnMainThreadAsync(() => DisplayAlert ("Alert", "You have been alerted", "OK"));`... and the alert has been shown for a less than half a second, and then hide behind the "Scan QR Code" button page. and the rest of the code isn't executing.. – Stavrogin May 17 '21 at 12:25
  • 1
    What is the "Scan QR Code"? Is it the page that appeared from the finally block's navigation? – Mihail Duchev May 18 '21 at 06:17
  • Let's say i have a page name `Index.cs`, there is a button name **Scan QR Code**, when i click on this button, using **ZXing.Net.Mobile**, i scan QR code.. when QR Code is scanned, it came back to `Index.cs`.. and it execute rest of the code in `Index.cs` page. – Stavrogin May 18 '21 at 06:28
  • I'm having difficulties understanding the problem. As far as I understood, the original problem (that the dialog isn't being shown) is fixed. If you have another problem, please ask another question and clarify it further. What I've understood only is that from some other place you are navigating again, which pushes another page on top of the navigation stack, but without more info, I really can't say what is causing this. P.S. If the original problem is fixed, please mark the answer as accepted (green check), so that it can help others. – Mihail Duchev May 18 '21 at 07:18
  • the dialog isn't showing.. I didn't mean that It navigate to another page, I mean when I click on "Scan QR Code" button, it start scanning the qr code (like this https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fwww.c-sharpcorner.com%2Farticle%2Fxamarin-android2%2FImages%2FScreenshot_1514635288.png&f=1&nofb=1), and when the scan is done, it hides this screen (https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fwww.c-sharpcorner.com%2Farticle%2Fxamarin-android2%2FImages%2FScreenshot_1514635288.png&f=1&nofb=1) as usual, but and start executing the rest of code, but no dialog – Stavrogin May 18 '21 at 07:39
  • Can you explain how many pages do you have, when do you have navigation (if any), what happens when you click this button, etc. You keep repeating that you don't have any navigation, but again - when the scanning is done, it "**hides**" the screen. Also, you said that the dialog appeared for 1 second or so and then it was hidden behind some other page!? Please elaborate on the flow as a whole. – Mihail Duchev May 18 '21 at 07:53
  • by **"hides"** the screen I meant this (https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fwww.c-sharpcorner.com%2Farticle%2Fxamarin-android2%2FImages%2FScreenshot_1514635288.png&f=1&nofb=1) – Stavrogin May 18 '21 at 07:59
  • i have `Index.cs` where the "Scan QR Code" button is. and when I scan the qr code and the rest of code is excecuted in `Index.cs`, in `finally { await NavigationService.NavigateToAsync(); }` .. it navigates to `NextViewModel`... – Stavrogin May 18 '21 at 07:59
  • **dialog appeared for 1 second or so and then it was hidden behind some other page** --- I meant that when I scan the qr code on this screen (https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fwww.c-sharpcorner.com%2Farticle%2Fxamarin-android2%2FImages%2FScreenshot_1514635288.png&f=1&nofb=1), when scan is completed, for a nano second, it shows the dialog, or as u told me to make an alert (it appears there), but it's for too short period that i can't even reads what's written on alert box (so, it's remained opened, and that's why it don't execute rest of code). – Stavrogin May 18 '21 at 08:04
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/232554/discussion-between-stavrogin-and-mihail-duchev). – Stavrogin May 18 '21 at 14:19
  • my problem is still there but I'll mark it as answer, maybe it help someone else.. and what is wrong with my code? any suggestion? – Stavrogin May 18 '21 at 14:43