Base solution for your next web application
Open Closed

Xamarin flurl timeout exception #6503


User avatar
0
Ricavir created

Hi,

I'm trying to sync some data from xamarin app to server. To do that, I'm listening to connectivity changes. If user is not connected and tries to save data, data is stored in cache.

Here is the code I'm using to sync data on xamarin app

public static class OfflineManager
    {        
        public static void ConnectivityChangedRegister()
        {
            CrossConnectivity.Current.ConnectivityChanged += async (sender, args) =>
            {
                if (args.IsConnected == true)
                {
                    await SyncOfflineEvents();
                }
            };
        }

        public static async Task SyncOfflineEvents()
        {
            if (Barrel.Current.Exists(CacheKeys.OfflineEvents))
            {
                var eventAppService = DependencyResolver.IocManager.Resolve<IEventAppService>();
                var offlineItemsToSync = Barrel.Current.Get<List<EventEditInput>>(CacheKeys.OfflineEvents);
                foreach (var offlineEvent in offlineItemsToSync)
                {
                    await WebRequestExecuter.Execute(
                        async () => await eventAppService.UpdateEventEdit(offlineEvent),
                        null,
                        null,
                        null,
                        false
                    );
                }
                Barrel.Current.Empty(CacheKeys.OfflineEvents);
            }
        }        

    }

It's a static class that I'm calling from App.xaml.cs like that : OfflineManager.ConnectivityChangedRegister();

When device becames connected and data is available to sync, the code runs correctly.

The issue is that I'm always getting a timeout exception for the first call (wich is a PUT).

I'm using WebRequestExecuter, thefore, when timeout exception is thrown a retry popup is displayed.

When I press "Ok" from this popup, the same call is sent to server correctly.

I think the problem occurs because the first call is not in a safe thread.

I've tried several things but always getting a timeout issue for the first call...

Can you please give me some support to avoid this timeout exception ?


5 Answer(s)
  • User Avatar
    0
    alper created
    Support Team

    ignore WebRequestExecuter and try to directly call await eventAppService.UpdateEventEdit(offlineEvent)

  • User Avatar
    0
    Ricavir created

    tks @alper

    I already tried it before creating this issue. I've tried again right now by ignoring WebRequestExecuter. I still have the same exception (App is closed brutaly because exception is not being managed).

    The same API call from a viewmodel command (fired by a button on a view) works like a charm. I really think that it's a threading issue but cannot find where to fix this.

    This API call is firing an exception only after receiving a CrossConnectivity.Current.ConnectivityChanged event...

    Here is the detailed exception :

    Unhandled Exception: Flurl.Http.FlurlHttpTimeoutException: Call timed out: PUT https://myapp.com/api/services/app/Event/UpdateEventEdit

    02-20 08:47:17.035 I/MonoDroid(23999): UNHANDLED EXCEPTION: Thread started: <Thread Pool> #19 02-20 08:47:17.055 I/MonoDroid(23999): Flurl.Http.FlurlHttpTimeoutException: Call timed out: PUT https://my-app.com/api/services/app/Event/UpdateEventEdit ---> System.OperationCanceledException: The operation was canceled. 02-20 08:47:17.055 I/MonoDroid(23999): at ModernHttpClient.NativeMessageHandler+<SendAsync>c__async0.MoveNext () [0x00422] in /Users/paul/code/paulcbetts/modernhttpclient/src/ModernHttpClient/Android/OkHttpNetworkHandler.cs:132 02-20 08:47:17.055 I/MonoDroid(23999): --- End of stack trace from previous location where exception was thrown --- 02-20 08:47:17.055 I/MonoDroid(23999): at System.Net.Http.HttpClient+<SendAsyncWorker>d__49.MoveNext () [0x000ca] in <25ebe1083eaf4329b5adfdd5bbb7aa57>:0 02-20 08:47:17.055 I/MonoDroid(23999): --- End of stack trace from previous location where exception was thrown --- 02-20 08:47:17.055 I/MonoDroid(23999): at Flurl.Http.FlurlRequest+<SendAsync>d__19.MoveNext () [0x0029e] in <c38761af4558433f81b1691eb86a1548>:0 02-20 08:47:17.055 I/MonoDroid(23999): --- End of inner exception stack trace --- 02-20 08:47:17.055 I/MonoDroid(23999): at Flurl.Http.FlurlRequest+<HandleExceptionAsync>d__23.MoveNext () [0x000f7] in <c38761af4558433f81b1691eb86a1548>:0 02-20 08:47:17.055 I/MonoDroid(23999): --- End of stack trace from previous location where exception was thrown --- 02-20 08:47:17.055 I/MonoDroid(23999): at Flurl.Http.FlurlRequest+<SendAsync>d__19.MoveNext () [0x0037d] in <c38761af4558433f81b1691eb86a1548>:0 02-20 08:47:17.055 I/MonoDroid(23999): --- End of stack trace from previous location where exception was thrown --- 02-20 08:47:17.055 I/MonoDroid(23999): at Flurl.Http.FlurlRequest+<SendAsync>d__19.MoveNext () [0x00486] in <c38761af4558433f81b1691eb86a1548>:0 02-20 08:47:17.055 I/MonoDroid(23999): --- End of stack trace from previous location where exception was thrown --- 02-20 08:47:17.055 I/MonoDroid(23999): at Flurl.Http.HttpResponseMessageExtensions+<ReceiveJson>d__01[T].MoveNext () [0x0006e] in <c38761af4558433f81b1691eb86a1548>:0 02-20 08:47:17.055 I/MonoDroid(23999): --- End of stack trace from previous location where exception was thrown --- 02-20 08:47:17.055 I/MonoDroid(23999): at ApiClient.AbpApiClient+<PutAsync>d__411[T].MoveNext () [0x00089] in C:\Users\Ricardo Lopes\source\repos\AspnetZero2\aspnet-core\src\Application.Client\ApiClient\AbpApiClient.cs:354 02-20 08:47:17.055 I/MonoDroid(23999): --- End of stack trace from previous location where exception was thrown --- 02-20 08:47:17.055 I/MonoDroid(23999): at ApiClient.AbpApiClient+<PutAsync>d__39`1[T].MoveNext () [0x000c7] in C:\Users\Ricardo Lopes\source\repos\AspnetZero2\aspnet-core\src\Application.Client\ApiClient\AbpApiClient.cs:337 02-20 08:47:17.055 I/MonoDroid(23999): --- End of stack trace from previous location where exception was thrown --- 02-20 08:47:17.055 I/MonoDroid(23999): at Events.ProxyEventAppService+

  • User Avatar
    0
    alper created
    Support Team

    Hi,

    I tried to test this case in Android emulator.

    I turn off WiFi and turn it on again.

    Then test code makes 2 requests to UserAppService.GetUserForEdit() method when it's online. Both requests get responses successfully.

    Maybe in real device; the first request fails because when it becomes online in the ConnectivityTypeChanged, the device may not be ready to make a real request. sometimes it needs to settle down connection or get new IP from router etc... So put a delay and try again ...

    Also you can try to make a request to google.com right after your WiFi status changes to online. So that we see if the problem is about the backend of our website or Flurl or about the delay

  • User Avatar
    0
    Ricavir created

    Tks @alper for this detailed answer & tests. On my side, I was testing by toggling on cellular network button from android emulator...I will test with Wifi button to see if same issue is raised.

    On other hand, I realized that on real android device, I did not have this timeout issue with same ode ! (just one time with an old android tablet).

    I will test by adding a small delay and give a feedback

  • User Avatar
    0
    ismcagdas created
    Support Team

    @ricavir please re-open if you couldn't solve the problem.