在 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 时被取消。
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 时被取消。