簡體   English   中英

如何防止等待執行?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM