У меня странная проблема с параллелизмом в написанном мной коде. Первое, что вы спросите, - почему я использую CF и DbModelBuilder ... ну, у меня есть ситуация, когда у меня может быть N-е количество баз данных, которые все будут идентичны, и я должен поддерживать разделение данных. Я использую CF, чтобы предотвратить серьезные проблемы с генерацией моделей, когда несколько разработчиков работают с моими моделями с помощью своего графического интерфейса. Увы, это основной код того, что я делаю.

Две строки записи консоли никогда не должны быть затронуты, и тем не менее они есть.

Не могли бы вы попробовать это и сообщить мне, в чем проблема?

Это консольное приложение Test Harness:

class Program
{
    static void Main(string[] args)
    {
        for (int i = 0; i < 100; i++)
        {
            var workerObject = new Worker();
            var workerThread = new Thread(workerObject.DoWork);
            workerThread.Start();
        }
    }
}

public class Worker
{
    public void DoWork()
    {
        var connections = new List<KeyValuePair<string, DynamicDb>>
            {
                new KeyValuePair<string, DynamicDb>("db1", new MyDynamicEntityLayer("db1").DynamicDb()),
                new KeyValuePair<string, DynamicDb>("db2", new MyDynamicEntityLayer("db2").DynamicDb())
            };

        foreach (var db in connections)
        {
            if (db.Key == "db1" && db.Value.ConnectionString.Contains("db2"))
                Console.WriteLine("THIS SHOULD NEVER HAPPEN!!! db1 : " + db.Value.ConnectionString);
            if (db.Key == "db2" && db.Value.ConnectionString.Contains("db1"))
                Console.WriteLine("THIS SHOULD NEVER HAPPEN!!! db2 : " + db.Value.ConnectionString);
        }
    }
}

Вот класс сущности:

public class MyDynamicEntityLayer
{
    public static string ConnectionString { get; set; }
    public MyDynamicEntityLayer(string db = null)
    {
        MakeAConnectionString(db);
        Database.SetInitializer<DynamicDb>(null);
    }

    public void MakeAConnectionString(string db)
    {
        var sqlBuilder = new SqlConnectionStringBuilder();
        if (db == "db1")
        {
            sqlBuilder.DataSource = "MySqlServer";
            sqlBuilder.InitialCatalog = "db1";
            sqlBuilder.ConnectTimeout = 180;
            sqlBuilder.IntegratedSecurity = true;
        }
        else
        {
            sqlBuilder.DataSource = "MySqlServer";
            sqlBuilder.InitialCatalog = "db2";
            sqlBuilder.ConnectTimeout = 180;
            sqlBuilder.IntegratedSecurity = true;
        }

        ConnectionString = sqlBuilder.ToString();
    }

    public DynamicDb DynamicDb()
    {
        var builder = new DbModelBuilder(DbModelBuilderVersion.Latest);
        TableMappingToBuilder(builder);
        var compiled = builder.Build(Database.DefaultConnectionFactory.CreateConnection(ConnectionString)).Compile();
        return new DynamicDb(compiled);
    }

    public void TableMappingToBuilder(DbModelBuilder builder)
    {
        builder.Configurations.Add(new EntityTypeConfiguration<ConcurrencyTest>());
        builder.Entity<ConcurrencyTest>().ToTable("ConcurrencyTest", "dbo");
    }
}

И мой файл DbContext CS:

public class DynamicDb : DbContext
{
    public string ConnectionString { get; set; }
    public DynamicDb(DbCompiledModel model)
        : base(MyDynamicEntityLayer.ConnectionString, model)
    {
        ConnectionString = MyDynamicEntityLayer.ConnectionString;
        ((IObjectContextAdapter)this).ObjectContext.CommandTimeout = 100;
    }
    public DbSet<ConcurrencyTest> ConcurrencyTests { get; set; }
}

public class ConcurrencyTest
{
    public int ID { get; set; }
    public string MyColumn { get; set; }
}
0
YurikoEX 24 Сен 2012 в 21:36
Какая проблема с параллелизмом? Если у вас возникла проблема, опишите ее, иначе ваш вопрос будет закрыт.
 – 
Ladislav Mrnka
24 Сен 2012 в 21:39
Две консольные линии записи никогда не должны быть затронуты.
 – 
YurikoEX
24 Сен 2012 в 21:42
Спасибо, что заглянули, Ладислав ... Я видел твои работы здесь. Вероятно, вы могли бы довольно быстро найти эту проблему!
 – 
YurikoEX
24 Сен 2012 в 21:50

1 ответ

Лучший ответ

Ваша проблема:

public class MyDynamicEntityLayer
{
    public static string ConnectionString { get; set; } // STATIC PROPERTY
    ...

}

Все рабочие потоки используют одно значение, хранящееся в этом свойстве, и борются за его изменение.

1
Ladislav Mrnka 24 Сен 2012 в 22:03