我有一个显示警报,询问用户是否要重试同步数据。我的问题是,当用户选择“是”时,我的方法重叠,导致我的应用程序崩溃。我有办法,例如当用户选择是,方法执行停止并重新执行方法?
这是我的完整代码:
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();
};
}
}
在我的例子中,我使用Task.Factory在后台执行方法,并使用CancellationToken来取消执行。
首先,您需要创建一个Token
参数,如下所示:
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();
之后,您可以重新执行您的方法。希望能帮助到你!