对象和多线程问题

本文关键字:问题 多线程 对象 | 更新日期: 2023-09-27 17:51:20

我们使用实体框架4作为我们的web应用程序和Ninject作为我们的DI容器。我们有一个日志表来记录我们应用程序中发生的所有事情,我们也有后台WCF工作流服务,它再次将日志写入日志表。

对于所有来自web的请求,我们使用

StandardScopeCallbacks.Request(ctx);

后端使用

StandardScopeCallbacks.ThreadScope(ctx);

我们的日志方法非常简单

 public void Log(string message, LogLevel level)
        {
             var log = new ApplicationLog()
                    {
                        LogDate = DateTime.Now,
                        Message = message,
                        LogLevel = Enum.GetName(typeof(LogLevel), level)
                    };
                    db.ApplicationLog.Add(log);
                    db.SaveChanges();          
        }

问题:如果我们有更多的线程在运行,那么我们会得到一个异常

System.Data.SqlClient。不允许新建事务因为还有其他线程在会话中运行。在

System.Data.SqlClient.SqlConnection。OnError (SqlException异常,布尔值breakConnection) atSystem.Data.SqlClient.TdsParser.ThrowExceptionAndWarning ()System.Data.SqlClient.TdsParser。运行(RunBehavior RunBehavior,SqlCommand cmdHandler, SqlDataReader dataStreamBulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObjectstateObj)System.Data.SqlClient.TdsParser.TdsExecuteTransactionManagerRequest (Byte []缓冲区,TransactionManagerRequestType请求,字符串transactionNameTransactionManagerIsolationLevel, Int32超时,SqlInternalTransaction事务,TdsParserStateObject在

System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransactionYukon (TransactionRequesttransactionName, transactionName, IsolationLevelSqlInternalTransaction internalTransaction, BooleanisDelegateControlRequest) at

System.Data.SqlClient.SqlInternalConnection.BeginSqlTransaction (IsolationLevel. iso,字符串transactionName)System.Data.SqlClient.SqlInternalConnection.BeginTransaction (IsolationLeveliso)System.Data.SqlClient.SqlConnection.BeginDbTransaction (IsolationLevelisolationLevel)System.Data.EntityClient.EntityConnection.BeginDbTransaction (IsolationLevelisolationLevel)

我知道我可以使用"using"语句创建新的上下文并写入日志表而没有任何问题。但是我不想这样做,因为这会使一切都比在threadscope中创建Context慢。

处理这种情况的最好方法是什么?我需要一个执行时间最少的实现。

如果你需要更多的信息,请留下评论。

对象和多线程问题

你应该听听Daniel的评论。NLog和Log4Net是更好的选择。

我不建议像Jalalx提到的那样锁定db,因为如果你有很多日志,它最终会减慢锁的执行速度。如果你没有大量的日志要写,那么一定要试一试。

两个选项,

  1. 为每个线程注册数据库连接/上下文,这样你就不必担心跨线程共享,它不会发生。
  2. 创建一个"DbConnectionFactory"来创建数据库连接/上下文,你可以在每个线程/执行的上下文中调用。

基本上它要么让Ninject管理它,要么创建一个抽象让你可以自己管理它

顺便说一句,ninject不是最慢的。net DI框架吗?