【问题标题】:Cancel Service Task when Net Goes off in Xamarin FormsXamarin Forms 中网络中断时取消服务任务
【发布时间】:2020-06-05 12:59:41
【问题描述】:
try
        {
            Console.WriteLine("MasterData Sync has started");
            IsMasterDataUpdating = true;
            Preferences.Set("IsMasterDataUpdating", true);
            Preferences.Set("MasterDataSyncServiceException", false);
            Console.WriteLine("Downloading Master Data has started");

            var token = masterDataSyncCancellationToken.Token;

            Task<ProductServiceModel> GetProductDataTask;
            Task<InvServiceModel> GetInventoryLineTask;
            Task<List<InvLineCost>> GetInvLineCostDataTask;
            Task<MiscDataMobileServiceModel> GetMiscellaniousMobileDataTask;
            Task<RecipeHierarchyModel> GetRecipeHierarhyDataTask;
            Task<UnknownInvStorage> GetUnknownStorageLocationDataTask;
            var tasks = new ConcurrentBag<Task>();

            GetProductDataTask = Task.Run(async () => await GetProductData("GetProductData", token), token);
            Console.WriteLine("Task {0} executing", "GetProductData");
            tasks.Add(GetProductDataTask);

            GetInventoryLineTask = Task.Run(async () => await GetInventoryLine("GetInventoryLine", token), token);
            Console.WriteLine("Task {0} executing", "GetInventoryLine");
            tasks.Add(GetInventoryLineTask);

            GetInvLineCostDataTask = Task.Run(async () => await GetInvLineCostData("GetInvLineCostData", token), token);
            Console.WriteLine("Task {0} executing", "GetInventoryLine");
            tasks.Add(GetInvLineCostDataTask);

            GetMiscellaniousMobileDataTask = Task.Run(async() => await GetMiscellaniousMobileData("GetMiscellaniousMobileData", token), token);
            Console.WriteLine("Task {0} executing", "GetMiscellaniousMobileData");
            tasks.Add(GetMiscellaniousMobileDataTask);

            GetRecipeHierarhyDataTask = Task.Run( async () => await GetRecipeHierarhyData("GetRecipeHierarhyData", token), token);
            Console.WriteLine("Task {0} executing", "GetRecipeHierarhyData");
            tasks.Add(GetRecipeHierarhyDataTask);

            GetUnknownStorageLocationDataTask = Task.Run(async () => await GetUnknownStorageLocationData("GetUnknownStorageLocationData", token), token);
            Console.WriteLine("Task {0} executing", "GetUnknownStorageLocationData");
            tasks.Add(GetUnknownStorageLocationDataTask);

            await Task.WhenAll(tasks.ToArray());


        }
        catch (OperationCanceledException)
        {
            Console.WriteLine($"\n{nameof(OperationCanceledException)} thrown\n");
        }
        finally
        {
            masterDataSyncCancellationToken.Dispose();
        }

现在我的 Get Product Data 方法发生服务调用:如下所示:

public async Task<ProductServiceModel> GetProductData(string TaskName, CancellationToken ct)
    {
        ProductServiceModel productServiceModel = null;
        try
        {
            productServiceModel = await _inventoryLineItems.GetProduct(RestaurantId, await GetLastMasterDataSyncDate());
        }
        catch (Exception ex)
        {
            Console.WriteLine("Exception at InventoryDashBoardPageModel : GetProductData " + ex.StackTrace);

        }

        if (ct.IsCancellationRequested)
        {
            Console.WriteLine("Task {0} was cancelled",
                              TaskName);
            ct.ThrowIfCancellationRequested();
        }

        return productServiceModel;
    }

控制台如下所示:

已开始下载主数据

2020-06-05 18:18:20.616419+0530 Inventory.MobileUi.iOS[24434:357126] 任务 GetProductData 正在执行

2020-06-05 18:18:20.622733+0530 Inventory.MobileUi.iOS[24434:357126] 任务 GetInventoryLine 正在执行

2020-06-05 18:18:20.624918+0530 Inventory.MobileUi.iOS[24434:357126] 任务 GetInventoryLine 正在执行

2020-06-05 18:18:20.628810+0530 Inventory.MobileUi.iOS[24434:357126] 任务 GetMiscellaniousMobileData 正在执行

2020-06-05 18:18:20.632101+0530 Inventory.MobileUi.iOS[24434:357126] 任务 GetRecipeHierarhyData 正在执行

2020-06-05 18:18:20.638025+0530 Inventory.MobileUi.iOS[24434:357126] 任务 GetUnknownStorageLocationData 正在执行

当网络关闭时,我只需调用

masterDataSyncCancellationToken.Cancel();

只有一个任务被取消,其余的永远不会被取消。

我做错了什么??

当我的网络中断时需要取消所有任务......

【问题讨论】:

  • 您必须将取消令牌传递给每个异步方法,每个方法都应将其作为输入并在每个异步方法调用中传递。
  • 以下方法中的取消过程是什么,它击中了 Web 服务 @AkashKava

标签: xamarin.forms offline cancellationtokensource


【解决方案1】:

您正在使用 Refit 调用您的 Api,但您的界面没有取消令牌作为参数。

例如,对于以下接口,IInventoryLineItemsApi,方法 GetInventoryLineItems 签名应如下所示:

GetInventoryLineItems(string restaurantId, string fromDate, CancellationToken ct);

这样,您的取消令牌将被传递给底层 HttpClient,因此您的 http 调用将在您调用 Cancel 时被取消。

【讨论】:

    【解决方案2】:
    public async Task<InvServiceModel> GetInventoryLineItems(string Restaurantid, string FromDate, CancellationToken ct)
            {
                InvServiceModel invservicemodel = null;
                HttpResponseMessage responseMessage = null;
    
                try
                {
                    var api = RestService.For<IInventoryLineItemsApi>(_httpClient);
                    responseMessage = await api.GetInventoryLineItems(Restaurantid, FromDate).ConfigureAwait(false);
                    if (responseMessage.StatusCode == System.Net.HttpStatusCode.OK)
                    {
                        string blobValidateResponse = await responseMessage.Content.ReadAsStringAsync();
                        invservicemodel = JsonConvert.DeserializeObject<InvServiceModel>(blobValidateResponse, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.None, NullValueHandling = NullValueHandling.Ignore });
                    }
                    else
                    {
                        analytics?.LogException(string.Format(ServiceConstants.ServiceException, responseMessage.StatusCode.GetHashCode().ToString() +
                                                                                            responseMessage.ReasonPhrase), serviceException, nameof(GetInventoryLineItems), nameof(InventoryLineItems));
                        throw serviceException;
    
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
    
                return invservicemodel;
            }
    

    【讨论】:

    • 如何取消这个网络服务调用?
    猜你喜欢
    • 2017-08-05
    • 1970-01-01
    • 2017-12-10
    • 2021-05-05
    • 1970-01-01
    • 2020-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多