C# 线程上下文与线程ID-使用CoreData和异步等待

C# 线程上下文与线程ID-使用CoreData和异步等待,c#,ios,multithreading,core-data,asynchronous,C#,Ios,Multithreading,Core Data,Asynchronous,我们正在Xamarin iOS C#项目中使用CoreData。由于并发问题,负责此区域的开发人员设计了测试System.Threading.Thread.CurrentThread.ManagedThreadId==1的代码,如果失败,将根据以下代码引发异常: public static NSManagedObjectContext ManagedObjectContext { get { if (System.Threading.Thread.CurrentThread.Manage

我们正在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#编写异步等待和后台处理代码,这才是真正需要的


谢谢

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

感谢您的回复。能否提供将mod.Perform()与async await一起使用的示例代码,并且在await Foo()返回时不会导致线程问题?Thanks@Neal不幸的是,我还没有为iOS编写任何.Net代码:)(虽然我是.Net开发人员,但我使用Objective-C)。无论如何,我会尝试编写示例代码,但我不能保证。。。