0

This is code from my handler:

   public class MoeZdravjeStatusCodeHandler : DelegatingHandler
    {
        public MoeZdravjeStatusCodeHandler(HttpMessageHandler innerHandler) : base(innerHandler) { }
        public IMojLekDataStore<Object> MojLekDataStore => DependencyService.Get<IMojLekDataStore<Object>>();
        public bool flag=true;
        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
           
            HttpResponseMessage response = new HttpResponseMessage();
            response = await base.SendAsync(request, cancellationToken);
            int status_code = (int)response.StatusCode;
            if (response.IsSuccessStatusCode)
            {
                return response;
            }
            else if(status_code == 401 && DependencyService.Get<ISharedFunctions>().GetUserValidation() == true )
            {
                try
                {
                    if (flag)
                    {
                        flag = false;
                        string date = DateTime.Today.ToString("yyyy-MM-dd") + "MoeZdravje";
                        string password = Helpers.ServiceHelper.HashPassword(date).ToString();
                        LoginMoeZdravje log = new LoginMoeZdravje();
                        log.EZBO = DependencyService.Get<ISharedFunctions>().GetPatient().Ezbo.ToString();
                        log.PASSWORD = password;
                        log.CONFIRMED_USER = 1;
                        var response_token = await MojLekDataStore.GetMoeZdravjeToken(log);
                        if (response_token != null && !String.IsNullOrEmpty(response_token.Token))
                        {
                            flag = true;
                            DependencyService.Get<ISharedFunctions>().SaveMoeZdravjeToken(response_token.Token);
                            await Application.Current.MainPage.DisplayAlert("", "ВАШИОТ ТОКЕН Е ОСВЕЖЕН", AppResources.BTNOK);
                            Application.Current.MainPage = new NavigationPage(new MainMenu());
                        }
                        else
                        {
                            flag = true;
                            await Application.Current.MainPage.DisplayAlert("", AppResources.SERVER_ERROR, AppResources.BTNOK);
                        }
                    }
                    else
                    {
                      CancellationTokenSource source = new CancellationTokenSource();
                      cancellationToken = source.Token;
                      source.Cancel();
                      source.Dispose();
                    }
                }
                catch (AggregateException ae)
                {
                    foreach (Exception e in ae.InnerExceptions)
                    {
                        if (e is TaskCanceledException)
                            Console.WriteLine("Unable to compute mean: {0}",
                                              ((TaskCanceledException)e).Message);
                        else
                            Console.WriteLine("Exception: " + e.GetType().Name);
                    }
                }
                finally
                {

                }
            }
            return response;
        }

I want when come to await MojLekDataStore.GetToken(log); block every async Task until finish this request because with this request i get a new token from my Api and need to save that token and call the requests to get the data with the new token. I have a tabbedPage with 4 async Tasks and this handler called two times for get a new token but i need one and to start work with the new token.

EDIT I added CancellationTokenSource source = new CancellationTokenSource(); but i dont know if this could stop other 3 async task ? The flag is used when first 401status_code request come .

Rajzer
  • 1,174
  • 11
  • 24
  • You could make a critical section inside `GetToken` which only can be entered by one "thead" at a time, so all others will have to wait. But once inside the critical section you will have to recheck if the current token is valid or not, because some other "thread" may already have created a new token. See this question about a critical section https://stackoverflow.com/questions/56236196/net-core-async-critical-section-if-working-on-same-entity – derpirscher Oct 29 '20 at 13:13
  • @derpirscher or is it possible to cancel all active Tasks when is status 401 ?This happens to me when i have tabbed page with more async Tasks – Rajzer Oct 29 '20 at 13:16
  • Use a lock : https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/lock-statement – jdweng Oct 29 '20 at 13:23
  • Does this answer your question? [How to cancel await Task that perform multiple task in C#](https://stackoverflow.com/questions/52089028/how-to-cancel-await-task-that-perform-multiple-task-in-c-sharp) You will have to pass your cancellation token to each of the tasks – derpirscher Oct 29 '20 at 13:26
  • @jdweng `lock` and `async/await` don't work together very well ... For instance you can't have an `await` inside a `lock {...}` – derpirscher Oct 29 '20 at 13:29
  • Is it possible to finish this and cancel all other active requests? – Rajzer Oct 29 '20 at 13:50
  • @derpirscher : Why not? As long as you are blocking with a await it should not matter. So await/async is fine. But async/await is not fine. – jdweng Oct 29 '20 at 14:55
  • @derpirscher what is the diffrence await/async , async/await? – Rajzer Oct 29 '20 at 14:57
  • @jdweng From the docs *[...] you can't use the await operator [...], inside the block of a lock statement [...]* (https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/await) I wasn't referencing to any order async/await or await/async. My point just was that you can't use `await` inside a `lock { ... }` The compile won't let you do this. – derpirscher Oct 29 '20 at 15:01
  • @derpirscher yeah yeah i understand u. I need just to get the token only once and because is tabbed page with 3 async task all call this await MojLekDataStore.GetToken(log); – Rajzer Oct 29 '20 at 15:03
  • @Rajzer Have a look at the referenced question. This will show you how to cancel a task. You will have to do this for all task you want to cancel. https://stackoverflow.com/questions/52089028/how-to-cancel-await-task-that-perform-multiple-task-in-c-sharp – derpirscher Oct 29 '20 at 15:09
  • @derpirscher : It says you can't use a lock inside a async. You can use an async inside a lock. – jdweng Oct 29 '20 at 15:45
  • @jdweng but what sense does an `async` inside a lock make, if you can't `await` it? – derpirscher Oct 29 '20 at 15:58
  • @derpirscher : None except if there is only a Async method. So remove the async. I just doing what the OP wanted. – jdweng Oct 29 '20 at 16:27

0 Answers0