在 Xamarin Forms 网络关闭时取消服务任务

Cancel Service Task when Net Goes off in Xamarin Forms

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();
        }

现在,发生服务调用的我的获取产品数据方法:如下所示:

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();

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

我做错了什么??

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

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;
        }

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

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

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

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