[英]How to prevent await to be executed?
我下面的代碼一次執行一個任務。
await App.TodoManager.SyncUserClientUpdate(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.UpdateContacts(contact);
await App.TodoManager.SyncContactsClientUpdate(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.SyncContactsMedia1ClientUpdate(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.SyncContactsMedia2ClientUpdate(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.SyncContactsMedia3ClientUpdate(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.SyncContactsMedia4ClientUpdate(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.SyncRetailerOutletClientUpdate(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.UpdateCAF(contact);
await App.TodoManager.SyncCAFClientUpdate(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.SyncCAFMedia1ClientUpdate(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.SyncCAFMedia2ClientUpdate(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.SyncCAFMedia3ClientUpdate(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.SyncCAFMedia4ClientUpdate(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.SyncCAFActivityClientUpdate(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.SyncEmailRecipientClientUpdate(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.SyncUserServerUpdate(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.SyncSystemSerialServerUpdate(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.SyncContactsServerUpdate(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.SyncRetailerOutletServerUpdate(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.SyncProvinceServerUpdate(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.SyncTownServerUpdate(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.SyncUserLogsClientUpdate(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.OnSyncComplete(host, database, ipaddress, contact);
我的問題是,每個任務都有一個互聯網連接檢查器,這意味着當應用程序檢測到該設備沒有互聯網連接時,它將檢查設備是否具有互聯網連接,它將顯示一個顯示警報,提示用戶。 當用戶選擇不重試時,他/她將被重定向到我的主頁。 問題來了,例如我的第一個任務( SyncUserClientUpdate )檢測到沒有連接,並且用戶選擇不重試,他/她將被重定向,但是當進入主頁時,將顯示另一個任務的顯示警報,並且當用戶選擇不重試時,同樣的事情也會發生,他/她將一遍又一遍地重定向到主頁,直到執行完最后一個功能。 選擇不重試時如何停止其他任務?
public async Task SyncUserClientUpdate(string host, string database, string domain, string contact, Action<string>SyncStatus)
{
SyncStatus("Initiating Client Update User Sync");
SyncStatus("Checking Connection To Server");
if (CrossConnectivity.Current.IsConnected)
{
var db = DependencyService.Get<ISQLiteDB>();
var conn = db.GetConnection();
string apifile = "sync-user-client-update-api.php";
SyncStatus("Checking Data From Local Database");
var datachanges = conn.QueryAsync<UserTable>("SELECT * FROM tblUser WHERE ContactID = ? AND LastUpdated > LastSync AND Deleted != '1'", contact);
var changesresultCount = datachanges.Result.Count;
if (changesresultCount > 0)
{
int clientupdate = 1;
for (int i = 0; i < changesresultCount; i++)
{
SyncStatus("Sending user changes to server " + clientupdate + " out of " + changesresultCount);
var uri = new Uri(string.Format("http://" + domain + "/TBSApi/" + apifile + "?Host=" + host + "&Database=" + database, string.Empty));
try
{
var result = datachanges.Result[i];
var userid = result.UserID;
var usrpassword = result.UsrPassword;
var usertypeid = result.UserTypeID;
var userstatus = result.UserStatus;
var lastsync = DateTime.Parse(current_datetime);
var lastupdated = result.LastUpdated;
var deleted = result.Deleted;
JObject json = new JObject
{
{ "UserID", userid },
{ "UsrPassword", usrpassword },
{ "ContactID", contact },
{ "UserTypeID", usertypeid },
{ "UserStatus", userstatus },
{ "LastUpdated", lastupdated },
{ "Deleted", deleted }
};
var response = await client.PostAsync(uri, new StringContent(json.ToString(), Encoding.UTF8, contentType));
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
if (!string.IsNullOrEmpty(content))
{
var dataresult = JsonConvert.DeserializeObject<List<ServerMessage>>(content, settings);
var dataitem = dataresult[0];
var datamessage = dataitem.Message;
if (datamessage.Equals("Inserted"))
{
await conn.QueryAsync<UserTable>("UPDATE tblUsers SET LastSync = ? WHERE ContactID = ?", DateTime.Parse(current_datetime), contact);
clientupdate++;
}
else
{
var retry = await App.Current.MainPage.DisplayAlert("Client Update User Sync Error", "Syncing failed.\n\n Error:\n\n" + datamessage + "\n\n Do you want to retry?", "Yes", "No");
if (retry)
{
await SyncUserClientUpdate(host, database, domain, contact, SyncStatus);
}
else
{
await Application.Current.MainPage.Navigation.PushAsync(new MainMenu(host, database, contact, domain));
}
}
}
}
else
{
var retry = await App.Current.MainPage.DisplayAlert("Client Update User Sync Error", "Syncing failed. Status Code:\n\n" + response.StatusCode, "Yes", "No");
if (retry)
{
await SyncUserClientUpdate(host, database, domain, contact, SyncStatus);
}
else
{
await Application.Current.MainPage.Navigation.PushAsync(new MainMenu(host, database, contact, domain));
}
}
}
catch (Exception ex)
{
Crashes.TrackError(ex);
var retry = await App.Current.MainPage.DisplayAlert("Client Update User Sync Error", "Syncing failed.\n\n Error:\n\n" + ex.Message, "Yes", "No");
if (retry)
{
await SyncUserClientUpdate(host, database, domain, contact, SyncStatus);
}
else
{
await Application.Current.MainPage.Navigation.PushAsync(new MainMenu(host, database, contact, domain));
}
}
}
var logType = "App Log";
var log = "Sent client updates to the server (<b>User</b>) <br/>" + "App Version: <b>" + Constants.appversion + "</b><br/> Device ID: <b>" + Constants.deviceID + "</b>";
int logdeleted = 0;
await Save_Logs(contact, logType, log, database, logdeleted);
}
}
else
{
var retry = await App.Current.MainPage.DisplayAlert("Client Update User Sync Error", "Syncing failed. Please connect to the internet to sync your data. Do you want to retry?", "Yes", "No");
if (retry)
{
await SyncUserClientUpdate(host, database, domain, contact, SyncStatus);
}
else
{
await Application.Current.MainPage.Navigation.PushAsync(new MainMenu(host, database, contact, domain));
}
}
}
您正在尋找的異步Tasks
稱為CancellationToken
您可以通過Stephen @Microsoft blogs來查看這個很棒的博客
基本上,您定義了取消令牌
CancellationToken token = …;
然后取消執行
public static async Task<T> WithCancellation<T>(
this Task<T> task, CancellationToken cancellationToken)
{
var tcs = new TaskCompletionSource<bool>();
using(cancellationToken.Register(
s => ((TaskCompletionSource<bool>)s).TrySetResult(true), tcs))
if (task != await Task.WhenAny(task, tcs.Task))
throw new OperationCanceledException(cancellationToken);
return await task;
}
默認情況下,display alert還返回一個布爾值,因此您的if語句如下所示,您不需要equals操作。
if (retry)
{..}
使用await
可以捕獲任務異常( 參考 ):
要捕獲異步任務引發的異常,請將await表達式放置在try塊中,然后將異常捕獲在catch塊中
如果任一個任務都將throw
,則后續任務將不會運行。
try
{
await Task1();
await Task2();
...
}
catch(SomeException e) { ... }
您只需要
throw new SomeException(...)
在任務調用的方法內部以確認用戶操作,然后用戶選擇取消。
有人可能會爭辯:“不要將異常用於流控制”。 是的,但是如果用戶可以中斷正常流程 ,則完全可以接受,因為用戶中斷程序流程是例外情況,因此不會正常發生,這是一個例外 。
很好的候選者是InvalidOperationException
,但是您可能想要創建自定義異常( UserInterruptException
)以更可靠地捕獲“用戶中斷”原因。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.