C# 任务中的领域异步使用
我试图更好地理解如何在异步场景中使用领域。据我所知,领域实例只能访问它创建的线程上的对象。因此,要执行异步事务,我需要使用C# 任务中的领域异步使用,c#,xamarin,realm,C#,Xamarin,Realm,我试图更好地理解如何在异步场景中使用领域。据我所知,领域实例只能访问它创建的线程上的对象。因此,要执行异步事务,我需要使用GetInstance(“SomeRealmFile”)创建一个新的领域实例 有一个名为Task WriteAsync(Action-Action)的函数,它可以在工作线程(后台)上执行写事务 下面是一个示例场景。应用程序需要发出web请求。因此,它运行一个异步任务函数去web上获取一些数据。请求成功返回,现在应用程序希望将该数据解析到一个领域对象中,并使用Realm.Man
GetInstance(“SomeRealmFile”)创建一个新的领域实例代码>
有一个名为Task WriteAsync(Action-Action)
的函数,它可以在工作线程(后台)上执行写事务
下面是一个示例场景。应用程序需要发出web请求。因此,它运行一个异步任务函数去web上获取一些数据。请求成功返回,现在应用程序希望将该数据解析到一个领域对象中,并使用Realm.Manage(T Obj)
将其持久化到数据库中。请注意,整个场景假设我们已经在UI主线程上创建了领域数据库
让我们假设此时我们希望留在后台线程上,在启动web请求的异步任务函数的上下文中
现在我们的情况是,我们通过var results=await WebFetch()获得web请求(数据)的结果代码>,可能改为使用类似TaskCompletionSource的东西,然后最后我们可以在工作线程上执行领域写事务。
我假设要在此时调用异步写事务,我们需要获取领域的一个新实例,并将其传递给WriteAsync()
函数
这引发了另一个问题,让我们假设在数据库编写事务之前,我们希望在编写东西之前进行一些查询和检查。如果我们在异步函数中执行这些查询,会发生什么?因为我以前尝试过很多奇怪的事情,有时候它可以工作,有时候查询只返回null(当然取决于查询的类型)。在主线程上完美工作的查询
编辑这可能是一个bug,异步函数中的查询非常不可靠
因此,为了清楚起见,我们仍然假设我们以前从异步任务(web fetch)返回,现在我们正在执行一些领域查询,然后调用任务WriteAsync(Action Action)
函数将数据写入数据库。这是正确的方法吗?在这一点上搞清楚就好了
最后一点,异步写事务是必要的吗?什么样的领域场景(写事务)可能会阻止UI线程足够长的时间,以至于它需要并证明可以在工作线程上执行(仅从移动开发的角度来看)
Edit下面链接的异步示例回答了这个问题,即任何占用大量cpu资源的进程。所以我们假设基本的领域写事务,例如管理50个对象的列表不需要是异步的
一个伪代码示例会很棒
编辑
在我的头顶上添加了一个代码示例
async Task RealmWritesAsync
{
var result = await WebFetch();
// Maybe do some queries here
var realm = Realm.GetInstance("RealmFile");
await realm.WriteAsync(realm =>
{
// Realm.Manage the results
});
}
Environment=Xamarin.iOS/Droid使用MvvmCross的PCL项目我最近在自己的应用程序中遇到了这个问题,但从未在StackOverflow上找到好的答案,因此我将分享我学到的知识
Realm
类上的WriteAsync
函数仅适用于需要在写事务中执行大量CPU繁重工作的情况。传递给lambda的Realm
实例是工作线程上的一个实例,对于在lambda内执行的操作,必须使用该实例而不是原始Realm
实例
如果您只想在不一定占用CPU的写事务中执行异步工作,则必须手动启动事务,然后在完成后提交它。我编写了一个扩展方法来简化这个过程,名为WriteTask
,以避免与现有的WriteAsync
函数发生冲突:
//
///Realm.Write的异步友好版本,这意味着work函数可以返回任务
///这将在交易范围内等待。
///
公共静态异步任务WriteTask(此领域,Func workFunction)
{
使用var transaction=realm.BeginWrite();
等待工作函数();
Commit();
}
注意,这使用了使用声明语法的C#8.0。如果不能使用C#8.0,只需将其替换为using块:
使用(var transaction=realm.BeginWrite())
{
等待工作函数();
Commit();
}
只要从主(UI)线程调用.WriteTask
方法,并且在lambda中等待任何任务时不使用.ConfigureAwait(false)
,这将允许在写事务中完成异步工作,而不需要单独的领域
实例。但是,请注意不要让多个并发异步操作同时尝试启动事务,因为这会引发异常。我最近在自己的应用程序中遇到了这种情况,但从未找到有关StackOverflow的好答案,因此我将与大家分享我学到的知识
Realm
类上的WriteAsync
函数仅适用于需要在写事务中执行大量CPU繁重工作的情况。传递给lambda的Realm
实例是工作线程上的一个实例,对于在lambda内执行的操作,必须使用该实例而不是原始Realm
实例
如果您只想在不一定占用CPU的写事务中执行异步工作,则必须手动启动事务,然后在完成后提交它。我编写了一个扩展方法来简化这个过程,名为WriteTask
,以避免与现有的WriteAsync
函数发生冲突:
//
///Realm.Write的异步友好版本,这意味着work函数可以返回任务
///这将在交易范围内等待。
///
公共静态异步任务WriteTask(此域)