使用MEF的多线程EF

时间:2012-12-06 14:01:07

标签: c# multithreading entity-framework task-parallel-library mef

我正在编写某种并行执行各种任务的调度程序。我使用MEF作为IoC容器。因为我知道共享一个ObjectContext的静态实例并不是一个好主意,所以我决定每个线程都有一个实例。我这样实现了它:

[Export(typeof(IDatabaseFactory))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class DatabaseFactory : IDatabaseFactory
{
    [Import]
    public IServiceResolver ServiceResolver { get; set; }

    [ThreadStatic]
    private static IEntityModel _dataContext;

    public IEntityModel Get()
    {
        if (_dataContext == null)
        {
            Debug.WriteLine("*************************");
            Debug.WriteLine(string.Format("Created Context Instance on Thread {0}", Thread.CurrentThread.ManagedThreadId));
            Debug.WriteLine("*************************");
        }

        return _dataContext ?? (_dataContext = ServiceResolver.GetService<IEntityModel>());
    }

    public void Dispose()
    {
        Debug.WriteLine("^^^^^^^^Disposing Context^^^^^^^^");

        if (_dataContext != null)
        {
            _dataContext.Dispose();
            _dataContext = null;
        }
    }
}

注意_dataContext字段的ThreadStatic属性;此代码失败,输出如下:

*************************
Created Context Instance on Thread 9
*************************
-- Running Main Thread on thread 9
-- Scheduling servicetask of type ActiveDirectorySynchronisationServiceTask on thread 14
-- Scheduling servicetask of type LogCleanerServiceTask on thread 15
-- Scheduling servicetask of type TranscriptParseServiceTask on thread 17
-- Scheduling servicetask of type MailServiceTask on thread 16
*************************
*************************
Created Context Instance on Thread 15
*************************
Created Context Instance on Thread 17
*************************
Created Context Instance on Thread 16
*************************
*************************

有以下错误消息:

{"The transaction operation cannot be performed because there are pending requests working on this transaction."}

请注意,实际错误并不总是相同的(有时“底层提供程序在打开时失败”等),这使我确信这是一个多线程问题。但我没有看到问题?

是否在ObjectContext的实例之间共享连接?我正在使用EF4.0,SQL Server Express 2008

2 个答案:

答案 0 :(得分:0)

您需要MARS(多个有效结果集),http://msdn.microsoft.com/en-us/library/h32h3abf(v=vs.80).aspx

EF尽可能尝试与SQL共享连接,这需要在连接字符串级别启用上述功能。当你同时拥有多个活动的上下文时(多线程应用程序或不完整的上下文),你才真正看到这个问题。

答案 1 :(得分:0)

我找到了解决这个问题的方法。我在ObjectContext类定义中添加了[PartCreationPolicy(CreationPolicy.NonShared)]。可能没有明确定义此属性,因此使用了共享引用。