我有一个Task Factory,可以启动使用REST的Task。
Task.Factory.StartNew(async () => await App.TodoManager.FirstTimeSyncUser(host, database, ipaddress, contact, SyncStatus))
.ContinueWith(async (t1) => await App.TodoManager.FirstTimeSyncSystemSerial(host, database, ipaddress, contact, SyncStatus))
.ContinueWith(async (t2) => await App.TodoManager.FirstTimeSyncContacts(host, database, ipaddress, contact, SyncStatus))
.ContinueWith(async (t3) => await App.TodoManager.FirstTimeSyncRetailerOutlet(host, database, ipaddress, contact, SyncStatus))
.ContinueWith(async (t4) => await App.TodoManager.FirstTimeSyncCAF(host, database, ipaddress, contact, SyncStatus))
.ContinueWith(async (t5) => await App.TodoManager.FirstTimeSyncCAFActivity(host, database, ipaddress, contact, SyncStatus))
.ContinueWith(async (t6) => await App.TodoManager.FirstTimeSyncEmailRecipient(host, database, ipaddress, contact, SyncStatus))
.ContinueWith(async (t7) => await App.TodoManager.FirstTimeSyncProvince(host, database, ipaddress, contact, SyncStatus))
.ContinueWith(async (t8) => await App.TodoManager.FirstTimeSyncTown(host, database, ipaddress, contact, SyncStatus))
.ContinueWith(async (t9) => await App.TodoManager.SyncUserLogsClientUpdate(host, database, ipaddress, contact, SyncStatus));
我遇到4个问题:
1.并非所有Task都在执行,这意味着它仅执行从FirstTimeSyncUser到FirstTimeSyncTown的功能。最后一个任务将不会执行。
2.有时,“任务重叠”的执行意味着正在执行2个或更多任务,而不是一次执行一个。
3.当出现异常错误时,不会显示来自每个Task的错误消息,这意味着当出现错误或异常时,每个Task都有一个try-catch系统,它应该显示一个Message框或DisplayAlert来通知使用错误是。 (示例如下)
4.我总是收到一个SQLite.SQLiteException:忙或SQLite.SQLiteException:数据库被锁定。
以下是示例:
public async Task FirstTimeSyncTown(string host, string database, string domain, string contact, Action<string>SyncStatus)
{
if (CrossConnectivity.Current.IsConnected)
{
var db = DependencyService.Get<ISQLiteDB>();
var conn = db.GetConnection();
string apifile = "first-time-sync-town-api.php";
int count = 0;
var uri = new Uri(string.Format("http://" + domain + "/TBSApi/" + apifile + "?Host=" + host + "&Database=" + database, string.Empty));
try
{
var response = await client.GetAsync(uri);
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
if (!string.IsNullOrEmpty(content))
{
var dataresult = JsonConvert.DeserializeObject<List<TownData>>(content, settings);
var datacount = dataresult.Count;
for (int i = 0; i < datacount; i++)
{
SyncStatus("Syncing town " + (count + 1) + " 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 + 1) + "\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;
await Save_Logs(contact, logType, log, database, logdeleted);
Preferences.Set("townchangelastcheck", current_datetime, "private_prefs");
}
}
else
{
var retry = await App.Current.MainPage.DisplayAlert("First-time Town Sync Error", "Syncing failed. Status Code:\n\n" + response.StatusCode, "Yes", "No");
if (retry.Equals(true))
{
await FirstTimeSyncTown(host, database, domain, contact, SyncStatus);
}
else
{
First_Time_OnSyncFailed();
}
}
}
catch (Exception ex)
{
Crashes.TrackError(ex);
var retry = await App.Current.MainPage.DisplayAlert("First-time Town Sync Error", "Syncing failed.\n\n Error:\n\n" + ex.Message, "Yes", "No");
if (retry.Equals(true))
{
await FirstTimeSyncTown(host, database, domain, contact, SyncStatus);
}
else
{
First_Time_OnSyncFailed();
}
}
}
else
{
var retry = await App.Current.MainPage.DisplayAlert("First-time Town Sync Error", "Syncing failed. Please connect to the internet to sync your data. Do you want to retry?", "Yes", "No");
if (retry.Equals(true))
{
await FirstTimeSyncTown(host, database, domain, contact, SyncStatus);
}
else
{
First_Time_OnSyncFailed();
}
}
}
我使用Task.Factory的目的是对Task执行进行排序。有没有更好的方法一个接一个地执行任务,这意味着除非当前任务完成执行,否则其他任务将无法执行?
答案 0 :(得分:0)
如果您的所有方法都是异步的,并且您想要做的就是让它们按顺序运行,那么为什么需要使用Task.Factory?您能不能像这样顺序等候他们?
await App.TodoManager.FirstTimeSyncUser(host, database, ipaddress, contact, SyncStatus));
await App.TodoManager.FirstTimeSyncSystemSerial(host, database, ipaddress, contact, SyncStatus));
await App.TodoManager.FirstTimeSyncContacts(host, database, ipaddress, contact, SyncStatus));
await App.TodoManager.FirstTimeSyncRetailerOutlet(host, database, ipaddress, contact, SyncStatus));
await App.TodoManager.FirstTimeSyncCAF(host, database, ipaddress, contact, SyncStatus));
await App.TodoManager.FirstTimeSyncCAFActivity(host, database, ipaddress, contact, SyncStatus));
await App.TodoManager.FirstTimeSyncEmailRecipient(host, database, ipaddress, contact, SyncStatus));
await App.TodoManager.FirstTimeSyncProvince(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.FirstTimeSyncTown(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.SyncUserLogsClientUpdate(host, database, ipaddress, contact, SyncStatus);
答案 1 :(得分:0)
Task.Factory.StartNew
和ContinueWith
都是非常低级的方法,通常应避免使用。特别是,他们不了解async
的代表;这就是为什么您看到执行重叠的原因。
我使用Task.Factory的目的是对Task执行进行排序。有没有更好的方法一个接一个地执行任务,这意味着除非当前任务完成执行,否则其他任务将无法执行?
是的。您应该使用async
和await
。
await App.TodoManager.FirstTimeSyncUser(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.FirstTimeSyncSystemSerial(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.FirstTimeSyncContacts(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.FirstTimeSyncRetailerOutlet(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.FirstTimeSyncCAF(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.FirstTimeSyncCAFActivity(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.FirstTimeSyncEmailRecipient(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.FirstTimeSyncProvince(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.FirstTimeSyncTown(host, database, ipaddress, contact, SyncStatus);
await App.TodoManager.SyncUserLogsClientUpdate(host, database, ipaddress, contact, SyncStatus);