Task Cancellation Issue

22 views Asked by At
public async Task<Tuple<List<Product>, CustomResponse>> GetAllProducts(string warehouseId, string pageNo, string pageSize, string lastSyncDateTime, bool isDeleted)
{
    CustomRequest req = new CustomRequest() { Code = "" };
    string url = $"{GlobalVariables.Instance.GetHost(Hosts.InventoryHost)}/InventoryItem/GetInventoryItems?warehouseId={warehouseId}&checkUpdate=true&lastSyncDateTime={lastSyncDateTime}&isDeleted={isDeleted}&pageNo={pageNo}&pageSize={pageSize}";
    List<Product> data = new List<Product>();
    try
    {
        if (!GlobalVariables.Instance.IsConnected)
        {
            return Tuple.Create(data, new CustomResponse() { ErrorCode = "PA0005", ResponseCode = ResponseCode.NoInternet, Response = req });
        }
        AddToken(GlobalVariables.Instance.BusinessName);
        using (HttpResponseMessage response = await ApiClient.GetAsync(url))
        {
            if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
            {
                return Tuple.Create(data, new CustomResponse() { ErrorCode = "PA0001", ResponseCode = ResponseCode.UnAuthorized, Response = req });
            }
            //CustomRequest req = await response.Content.ReadAsAsync<CustomRequest>();
            string stringReq = await response.Content.ReadAsStringAsync();
            req = !string.IsNullOrEmpty(stringReq)
                        ? JsonConvert.DeserializeObject<CustomRequest>(stringReq.ToString())
                        : new CustomRequest();
            if (response.IsSuccessStatusCode)
            {
                if (req.Success)
                {
                    if (req.Data != null)
                    {
                        data = !string.IsNullOrEmpty(req.Data.ToString())
                        ? JsonConvert.DeserializeObject<List<Product>>(req.Data.ToString())
                        : new List<Product>();
                        return Tuple.Create(data, new CustomResponse() { ErrorCode = "PA0004", ResponseCode = ResponseCode.Success, Response = req });
                    }
                    else
                    {
                        return Tuple.Create(data, new CustomResponse() { ErrorCode = "PA0008", ResponseCode = ResponseCode.NotFound, Response = req });
                    }
                }
                return Tuple.Create(data, new CustomResponse() { ErrorCode = "PA0007", ResponseCode = ResponseCode.ServerError, Response = req });
            }
            else
            {
                return Tuple.Create(data, new CustomResponse() { ErrorCode = "PA0002", ResponseCode = ResponseCode.ServerError, Response = req });
            }
        }
    }
    catch (TimeoutException)
    {
        return Tuple.Create(data, new CustomResponse() { ErrorCode = "PA0003", ResponseCode = ResponseCode.TimeOut, Response = req });
    }
    catch (TaskCanceledException ex)
    {
        return Tuple.Create(data, new CustomResponse() { ErrorCode = "PA0013", ResponseCode = ResponseCode.TaskCancelled, Response = req });
    }
    catch (Exception ex)
    {
        GlobalVariables.Instance.Logger.Log(ex.ToString(), LoggerHelper.LogType.Exception);
    }
    return Tuple.Create(data, new CustomResponse() { ErrorCode = "PA0006", ResponseCode = ResponseCode.InternalError, Response = req });
}

here is my code i am getting all the products from server and store them into db but i have almost 30k products on server when i this function after using statement it cancels the task i dont what is happening sometimes task cancelled after getting the 7k products and sometime 19k but never get all the products anf after that i store them into db.

public async Task GetAllItemsFromServer(bool isError = false)
{
    bool reloadFB = false;
    try
    {
        if (isSyncProducts)
            return;
        GlobalVariables.Instance.Logger.Log("-> Sync products from server", LoggerHelper.LogType.Info);
        isSyncProducts = true;
        bool isDel = true;
        string timeToSaved = DateTime.UtcNow.ToString();
        try
        {
            var lastInventorySyncTime = await _settingService.GetSetting<string>(SettingKey.LastInventorySyncTime);
            if (lastInventorySyncTime == null)
            {
                lastInventorySyncTime = new DateTime().ToString();
                isDel = false;
            }
            bool isLastLoop = true;
            int pageNo = 0;
            do
            {
                var res = await _productService.GetAllProducts(GlobalVariables.Instance.Business.Location.LocationId.ToString(), pageNo.ToString(), "1000", lastInventorySyncTime, isDel);
                if (res.Item2.ResponseCode == ResponseCode.Success)
                {
                    if (res.Item1.Any())
                        reloadFB = true;
                    res.Item1.Where(x => x.ImageThumbnail == null || x.ImageThumbnail == "").ForEach(x => { x.ImageThumbnail = "noproduct"; });
                    res.Item1.Where(x => x.Image == null || x.Image == "").ForEach(x => { x.Image = "noproduct"; });
                    await Device.InvokeOnMainThreadAsync(() =>
                    {
                        try
                        {
                            res.Item1.ForEach(x =>
                            {
                                x.ItemNameLower = x.ItemName.ToLower();
                                x.BarcodeLower = x.Barcode.ToLower();
                                x.SkuCodeLower = x.SkuCode.ToLower();
                            });
                            _dBService.AddOrUpdateRange<Product>(res.Item1);
                            var delProducts = _dBService.FindBy<Product>(x => x.IsDeleted);
                            _dBService.DeleteRange<Product>(delProducts);
                        }
                        catch (Exception ex)
                        {
                            GlobalVariables.Instance.Logger.Log(ex.ToString(), LoggerHelper.LogType.Exception);
                        }
                        GlobalVariables.Instance.Logger.Log($"-> Successfuly synced products({res.Item1.Count}) from server", LoggerHelper.LogType.Info);
                    });
                    pageNo++;
                    if (res.Item1.Count < 1000)
                    {
                        await _settingService.SaveSetting(SettingKey.IsInventorySynced, true);
                        await _settingService.SaveSetting(SettingKey.LastInventorySyncTime, timeToSaved);
                        isLastLoop = false;
                    }
                }
                else
                {
                    isLastLoop = false;
                    if (isError)
                        await _errorReportingService.GetError(res.Item2);
                }
            }
            while (isLastLoop);
        }
        catch (Exception ex)
        {
            GlobalVariables.Instance.Logger.Log(ex.ToString(), LoggerHelper.LogType.Exception);
        }
        try
        {
            var isInventorySynced = await _settingService.GetSetting<bool>(SettingKey.IsInventorySynced);
            if (isInventorySynced)
            {
                var lastQtySyncTime = await _settingService.GetSetting<string>(SettingKey.LastQtySyncTime);
                if (lastQtySyncTime == null)
                {
                    var lastInventorySyncTime = await _settingService.GetSetting<string>(SettingKey.LastInventorySyncTime);
                    lastQtySyncTime = lastInventorySyncTime;
                }
                if (lastQtySyncTime != null)
                {
                    timeToSaved = DateTime.UtcNow.ToString();
                    var res = await _productService.GetInventoryStocks(GlobalVariables.Instance.Business.Location.LocationId.ToString(), "0", "10000", lastQtySyncTime, _cancellationTokenSource.Token);
                    if (res.Item2.ResponseCode == ResponseCode.Success)
                    {
                        foreach (var item in res.Item1)
                        {
                            await Device.InvokeOnMainThreadAsync(() =>
                            {
                                try
                                {
                                    var itm = _dBService.GetFirst<Product>(x => x.ItemSKUId == item.ItemSkuId);
                                    if (itm != null)
                                    {
                                        _dBService.Write(() =>
                                        {
                                            itm.Quantity = item.Quantity;
                                        });
                                    }
                                }
                                catch (Exception ex)
                                {
                                    GlobalVariables.Instance.Logger.Log(ex.ToString(), LoggerHelper.LogType.Exception);
                                }
                            });
                        }
                        await _settingService.SaveSetting(SettingKey.LastQtySyncTime, timeToSaved);
                    }
                }
            }
        }
        catch (Exception ex)
        {
            GlobalVariables.Instance.Logger.Log(ex.ToString(), LoggerHelper.LogType.Exception);
        }
        await DependencyService.Get<FunctionViewModel>().GetProductStocks(false);
        if (reloadFB)
            DependencyService.Get<FunctionViewModel>().PerformAction(FunctionActions.SelectFirstTab);
    }
    catch (Exception ex)
    {
        GlobalVariables.Instance.Logger.Log(ex.ToString(), LoggerHelper.LogType.Exception);
    }
    finally
    {
        isSyncProducts = false;
    }
}

Tell i am getting the task cancel exception and i added the timeout of 60sec

protected static HttpClient ApiClient { get; set; }
public ApiHelper()
{
    //if (Stopwatch==null)
    //{
    //    Stopwatch = new Stopwatch();
    //}
    if (ApiClient == null)
    {
        if (Constants.ApplicationMode == AppMode.Production)
        {
            ApiClient = new HttpClient(new HttpClientHandler() { AllowAutoRedirect = true }) { Timeout = TimeSpan.FromSeconds(60) };
        }
        else
        {
            ApiClient = new HttpClient(new HttpClientHandler() { AllowAutoRedirect = true, ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; } }) { Timeout = TimeSpan.FromSeconds(60) };
        }

        ApiClient.DefaultRequestHeaders.Accept.Clear();
        ApiClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    }
    Formatters = new List<MediaTypeFormatter>();
    Formatters.Add(new TextMediaTypeFormatter());

}

i have above 30k products i am getting from server, right now when i get i am unable to get all bcz of task cancel i think i wanna get all the products from server and store them to db.

0

There are 0 answers