如何在C#/ XamarinForms中停止和重新执行方法?

时间:2019-04-12 00:57:49

标签: c# xamarin xamarin.forms xamarin.android

我有一个显示警报,询问用户是否要重试同步数据。我的问题是,当用户选择“是”时,我的方法重叠,导致我的应用程序崩溃。我有一种方法,例如当用户选择是时,方法执行停止并重新执行该方法?

这是我的完整代码:

 public async void FirstTimeSyncTown(string host, string database, string contact, string ipaddress)
    {
        try
        {
            syncStatus.Text = "Checking internet connection";

            string apifile = "first-time-sync-town-api.php";

            if (CrossConnectivity.Current.IsConnected)
            {
                syncStatus.Text = "Initializing first-time town sync";

                var db = DependencyService.Get<ISQLiteDB>();
                var conn = db.GetConnection();

                var getData = conn.QueryAsync<TownTable>("SELECT * FROM tblTown WHERE Deleted != '1'");
                var resultCount = getData.Result.Count;

                var current_datetime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                int count = 1;

                var settings = new JsonSerializerSettings
                {
                    NullValueHandling = NullValueHandling.Ignore,
                    MissingMemberHandling = MissingMemberHandling.Ignore
                };

                if (resultCount == 0)
                {
                    syncStatus.Text = "Getting data from the server";

                    var link = "http://" + ipaddress + ":" + Constants.port + "/" + Constants.apifolder + "/api/" + apifile;
                    string contentType = "application/json";
                    JObject json = new JObject
                    {
                        { "Host", host },
                        { "Database", database }
                    };

                    HttpClient client = new HttpClient();
                    var response = await client.PostAsync(link, new StringContent(json.ToString(), Encoding.UTF8, contentType));

                    if (response.IsSuccessStatusCode)
                    {
                        var content = await response.Content.ReadAsStringAsync();

                        if (!string.IsNullOrEmpty(content))
                        {
                            try
                            {
                                var dataresult = JsonConvert.DeserializeObject<List<TownData>>(content, settings);
                                var datacount = dataresult.Count;

                                for (int i = 0; i < datacount; i++)
                                {
                                    syncStatus.Text = "Syncing town " + count + " out of " + datacount;

                                    var item = dataresult[i];
                                    var townID = item.TownID;
                                    var provinceID = item.ProvinceID;
                                    var town = item.Town;
                                    var lastsync = DateTime.Parse(current_datetime);
                                    var lastupdated = item.LastUpdated;
                                    var deleted = item.Deleted;

                                    var insertdata = new TownTable
                                    {
                                        TownID = townID,
                                        ProvinceID = provinceID,
                                        Town = town,
                                        LastSync = lastsync,
                                        LastUpdated = lastupdated,
                                        Deleted = deleted
                                    };

                                    await conn.InsertOrReplaceAsync(insertdata);

                                    count++;
                                }

                                synccount += "Total synced town: " + count + "\n";

                                var logType = "App Log";
                                var log = "Initialized first-time sync (<b>Town</b>)  <br/>" + "App Version: <b>" + Constants.appversion + "</b><br/> Device ID: <b>" + Constants.deviceID + "</b>";
                                int logdeleted = 0;

                                Save_Logs(contact, logType, log, database, logdeleted);
                            }
                            catch
                            {
                                var retry = await DisplayAlert("Application Error", "Syncing failed. Failed to send the data.\n\n Error:\n\n" + content + "\n\n Do you want to retry?", "Yes", "No");

                                if (retry.Equals(true))
                                {
                                    FirstTimeSyncTown(host, database, contact, ipaddress);
                                }
                                else
                                {
                                    First_Time_Sync_Failed();
                                }
                            }
                        }

                        Preferences.Set("townchangelastcheck", current_datetime, "private_prefs");

                        SyncUserLogsClientUpdate(host, database, contact, ipaddress);
                    }
                    else
                    {
                        var retry = await DisplayAlert("Application Error", "Syncing failed. Please connect to the internet to sync your data. Do you want to retry?", "Yes", "No");

                        if (retry.Equals(true))
                        {
                            FirstTimeSyncTown(host, database, contact, ipaddress);
                        }
                        else
                        {
                            First_Time_Sync_Failed();
                        }
                    }
                }
                else
                {
                    SyncTownServerUpdate(host, database, contact, ipaddress);
                }
            }
            else
            {
                var retry = await DisplayAlert("Application Error", "Syncing failed. Please connect to the internet to sync your data. Do you want to retry?", "Yes", "No");

                if (retry.Equals(true))
                {
                    FirstTimeSyncTown(host, database, contact, ipaddress);
                }
                else
                {
                    First_Time_Sync_Failed();
                }
            }
        }
        catch (Exception ex)
        {
            Crashes.TrackError(ex);
            var retry = await DisplayAlert("Application Error", "Syncing failed. Failed to send the data.\n\n Error:\n\n" + ex.Message.ToString() + "\n\n Do you want to retry?", "Yes", "No");

            if (retry.Equals(true))
            {
                FirstTimeSyncTown(host, database, contact, ipaddress);
            }
            else
            {
                First_Time_Sync_Failed();
            };
        }
    }

1 个答案:

答案 0 :(得分:0)

就我而言,我使用Task.Factory来在后台执行方法,还使用CancellationToken来取消执行。

首先,您需要像这样创建一个public CancellationTokenSource Ts { get; set; } = new CancellationTokenSource(); 参数:

// Get Token for Task.Factory
var ct = Ts.Token;
try 
{
    Task.Factory.StartNew(() => 
    {
       // your code for background task
       ...
       // This is for defining whether user cancelled
       // and in that place your code stops
       if (ct.IsCancellationRequested) 
       {
           // do the staff and return
           return;
       }
    }, ct);
}
catch (AggregateException ex) 
{
    Console.WriteLine(ex.Message);
}

(我将其作为该类的公共全局参数来从外部访问)。

执行后台方法时,我使用以下代码行:

// Call it to stop thread
yourCustomClass.Ts.Cancel();

当用户单击“取消”时,我将处理此事件并称为:

int const & &&

之后,您可以重新执行方法。希望对您有帮助!