использует маршрут, полученный в строке 100, а затем снова доступен по строке 109 после ожидаемого вызова на 104, опасно?
Да, на следующей итерации foreach вы получите другой управляемый поток, а Realm сгенерирует другое исключение доступа к потоку.
Ключ в том, чтобы использовать SynchronizationContext
, чтобы ваши ожидающие продолжения находились в одном потоке (и, конечно, поскольку вы будете в другом потоке, пропустите использование асинхронных методов на основе Царства)
Использование Nito.AsyncEx Стивена Клири (он король контекстов синхронизации ?)
re: как я могу принудительно ожидать завершения в том же потоке?
var yourRealmInstanceThread = new AsyncContextThread();
await yourRealmInstanceThread.Factory.Run(async () =>
{
var asyncExBasedRealm = Realm.GetInstance();
var routes = asyncExBasedRealm.All<UserModel>();
foreach (var route in routes)
{
// map it
// post it
await Task.Delay(TimeSpan.FromMilliseconds(1)); // Simulate some Task, i.e. a httpclient request....
// The following continuations will be executed on the proper thread
asyncExBasedRealm.Write(() => route.Uploaded = true);
}
});
Использование SushiHangover.RealmThread
Я недавно написал simple SynchronizationContext для Realm, он работает для моих нужд и имеет специальный API для Realm.
using (var realmThread = new RealmThread(realm.Config))
{
await realmThread.InvokeAsync(async myRealm =>
{
var routes = myRealm.All<UserModel>();
foreach (var route in routes)
{
// map it
// post it
await Task.Delay(TimeSpan.FromMilliseconds(1));
// The following continuations will be executed on the proper thread
myRealm.Write(() => route.Uploaded = true);
}
});
}
Примечание: Для тех, кто плохо понимает SynchronizationContext
, я настоятельно рекомендую использовать Nito.AsyncEx
в качестве универсального решения, которое хорошо поддерживается и в связи с тем, что это от Стивена Клири .. Я использую его в подавляющем большинстве своих проектов.