【问题标题】:Thread Context vs. Thread ID - using CoreData with Async Await线程上下文与线程 ID - 将 CoreData 与 Async Await 结合使用
【发布时间】:2015-02-04 20:48:44
【问题描述】:

我们在 Xamarin iOS C# 项目中使用 CoreData。由于并发问题,负责该领域的开发人员设计了测试System.Threading.Thread.CurrentThread.ManagedThreadId == 1 的代码,如果失败,则根据以下代码引发异常:

public static NSManagedObjectContext ManagedObjectContext {
get
{
    if (System.Threading.Thread.CurrentThread.ManagedThreadId == 1)
    {
        return MainMOC;
    }
    else
    {
            if (_context == null) {
            System.Diagnostics.Debugger.Break();
            // Hey, don't ignore this exception, fix it
            // if you don't fix it, all values coming from core data are suspect
            throw new Exception("attempting to use a temp context without calling BeginBackgroundContext()");
        }
        return _context;
    }
}

}

这迫使开发人员对任何后台调用使用代码模式,如下所示:

InvokeInBackground(()=> {

NSManagedObjectContext context = new NSManagedObjectContext(NSManagedObjectContextConcurrencyType.PrivateQueue);
context.ParentContext = DataSource.MainMOC;
context.PerformAndWait(() => {

    try {

        DataSource.SetContextForThread(context);

        // update the UI
        this.InvokeOnMainThread(delegate
            {

            // do your code here

            });
    } catch (Exception e) {

            // log exception here
    }

});
DataSource.ClearContextForThread();

}

这对于创建 NSManagedObjectContext、执行代码、然后保存上下文等线程真的有必要吗?我认为这是矫枉过正且过于严格。我们应该只关心线程上下文而不是测试线程 ID?现在我不确定线程​​上下文和 ID 是否相同,但我相信它们是不同的。我假设的上下文本质上是 UI 线程和后台线程。因此,如果我们在 UI 线程上创建上下文,请在带有 .ConfigureAwait(true) 的方法上使用 async await 以确保我们返回调用的“上下文”代码应该仍然有效吗?就目前而言,如果您使用 async await 知道您不能保证返回相同的上下文,更不用说相同的线程 ID,工程师在顶部代码块中创建的陷阱将导致失败(故意)。

我只想根据需要编写复杂的代码,那么 CoreData 真正需要什么知道 SQLite 后端的单线程性质,并且仍然可以轻松地使用 C# 中的异步等待和后台进行编码?

谢谢

【问题讨论】:

    标签: c# ios multithreading core-data asynchronous


    【解决方案1】:

    CoreData 不是线程安全的,您需要为每个线程创建新的 ManagedObjectContext。 ManagedObjectContext 很便宜,所以它不是矫枉过正。对于 async/await,使用 moc.Perform() 应该可以正常工作。

    【讨论】:

    • 感谢您的回复。您能否提供将 mod.Perform() 与 async await 安全使用的示例代码,并且在 await Foo() 返回时不会导致线程问题?谢谢
    • @Neal 不幸的是没有,因为我还没有为 iOS 编写任何 .Net 代码:)(虽然我是 .Net 开发人员,但我使用的是 Objective-C)。无论如何,我会尝试编写示例代码,但我不保证......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-15
    • 1970-01-01
    • 2015-12-25
    • 1970-01-01
    • 1970-01-01
    • 2018-07-18
    • 2020-08-27
    相关资源
    最近更新 更多