我有以下电话(实际上比这多一些-这是这里要讨论的整体方法):
ThreadPool.QueueUserWorkItem(Database.Instance.RefreshEventData);
ThreadPool.QueueUserWorkItem(Database.Instance.RefreshLocationData);
ThreadPool.QueueUserWorkItem(Database.Instance.RefreshActData);
第一点是-这样调用WCF服务的方法可以吗?我尝试用菊花链将它们链接起来,结果一团糟。
上面调用的一种刷新方法的示例是(它们都遵循相同的模式,只是调用不同的服务并填充不同的表):
public void RefreshEventData (object state)
{
Console.WriteLine ("in RefreshEventData");
var eservices = new AppServicesClient (new BasicHttpBinding (), new EndpointAddress (this.ServciceUrl));
//default the delta to an old date so that if this is first run we get everything
var eventsLastUpdated = DateTime.Now.AddDays (-100);
try {
eventsLastUpdated = (from s in GuideStar.Data.Database.Main.Table<GuideStar.Data.Event> ()
orderby s.DateUpdated descending
select s).ToList ().FirstOrDefault ().DateUpdated;
} catch (Exception ex1) {
Console.WriteLine (ex1.Message);
}
try {
eservices.GetAuthorisedEventsWithExtendedDataAsync (this.User.Id, this.User.Password, eventsLastUpdated);
} catch (Exception ex) {
Console.WriteLine ("error updating events: " + ex.Message);
}
eservices.GetAuthorisedEventsWithExtendedDataCompleted += delegate(object sender, GetAuthorisedEventsWithExtendedDataCompletedEventArgs e) {
try {
List<Event> newEvents = e.Result.ToList ();
GuideStar.Data.Database.Main.EventsAdded = e.Result.Count ();
lock (GuideStar.Data.Database.Main) {
GuideStar.Data.Database.Main.Execute ("BEGIN");
foreach (var s in newEvents) {
GuideStar.Data.Database.Main.InsertOrUpdateEvent (new GuideStar.Data.Event {
Name = s.Name,
DateAdded = s.DateAdded,
DateUpdated = s.DateUpdated,
Deleted = s.Deleted,
StartDate = s.StartDate,
Id = s.Id,
Lat = s.Lat,
Long = s.Long
});
}
GuideStar.Data.Database.Main.Execute ("COMMIT");
LocationsCount = 0;
}
} catch (Exception ex) {
Console.WriteLine("error InsertOrUpdateEvent " + ex.Message);
} finally {
OnDatabaseUpdateStepCompleted (EventArgs.Empty);
}
};
}
OnDatabaseUpdateStepCompleted-只需在调用updateComplete计数器时对其进行迭代,并且当知道所有服务都恢复正常后,它将删除等待的微调器并继续运行该应用程序。
这第一次可以正常工作-但有时它与以下其中一项不兼容:http://monobin.com/__m6c83107d
我认为第一个问题是-这一切还好吗?我不习惯使用线程和锁,所以我正在为自己开拓新的领域。这样使用QueueUserWorkItem可以吗?在进行批量插入/更新之前,我应该使用锁吗?一个例子:
public void InsertOrUpdateEvent(Event festival){
try {
if (!festival.Deleted) {
Main.Insert(festival, "OR REPLACE");
}else{
Main.Delete<Event>(festival);
}
} catch (Exception ex) {
Console.WriteLine("InsertOrUpdateEvent failed: " + ex.Message);
}
}
然后下一个问题是-导致这些sqlite问题的我在做错什么?
w://
最佳答案
抱歉,没有具体答案,但有一些想法:
SqlLite甚至是线程安全的吗?我不确定-可能不是(对于包装器来说不是)。您可以锁定更全局的对象,这样就不会同时插入两个线程吗?
MT GC可能会变得有点过分热情,并在使用字符串之前将其释放。也许在插入过程中保留对它的本地引用?我曾经在视图控制器中发生过这种情况,我将它们放在一个数组中(特别是tabcontrollers),但是如果我没有在引用中保留成员变量,它们就会被GC。
您能以线程方式获取数据,然后将所有数据排队并插入单个线程中吗?无论如何,将Atleast作为测试。