为了账号安全,请及时绑定邮箱和手机立即绑定

在具有 2 个不同 .SVC 文件的多线程环境中调用 WCF 服务。同时调用两个服务时出错

在具有 2 个不同 .SVC 文件的多线程环境中调用 WCF 服务。同时调用两个服务时出错

C#
慕田峪7331174 2021-07-13 21:21:51
我有一个应用程序,它有两个特定于两个不同模块的 .SVC 文件。在现有的应用程序中,我们在同一个线程中一个接一个地进行调用。我从来没有问题。作为重构的一部分,我清理了它们从两个不同的线程调用这些服务(第一个线程调用第一个方法,第二个线程调用第二个方法)。这两种方法甚至是不同的。有时代码在执行时没有任何问题。但有时,我收到以下错误消息,说找不到实例。同样,此错误并不总是发生。      Exception:                RMS Conversion failed : System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail]: ComponentActivator: could not instantiate Axis.Edc.Service.RMS.RMSConversionService (Fault Detail is equal to An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is:    Castle.MicroKernel.ComponentActivator.ComponentActivatorException: ComponentActivator: could not instantiate RMS.RMSConversionService ----> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ----> System.InvalidOperationException: The context cannot be used while the model is being created. This exception may be thrown if the context is used inside the OnModelCreating method or if the same context instance is accessed by multiple threads concurrently. Note that instance members of DbContext and related classes are not guaranteed to be thread safe.       at System.Data.Entity.Internal.LazyInternalContext.InitializeContext()       at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)       at System.Data.Entity.Internal.Linq.InternalSet`1.Initialize()       at System.Data.Entity.Internal.Linq.InternalSet`1.GetEnumerator...).这是对服务的代码调用:public EnumConversionStatus GenerateRmsImportFiles(int submissionId)        {            lock (new object())            {                using (var client = new RMSConversionService.RMSConversionServiceClient())                {                    var result = client.GenerateRmsImportFiles(submissionId);                    client.Close();                    return result;                }            }        }这里我们有两个不同的端点用于 2 个不同的 SVC 服务。也在这里我们有锁。我不确定如何准确解决此错误?
查看完整描述

1 回答

?
森林海

TA贡献2011条经验 获得超2个赞

lock (new object())每次使用都会创建一个新对象。这意味着每个线程锁定不同的对象。这根本不是锁定。


如果您的两个服务不使用相同的资源,则不需要锁定。但是正如我从您的异常中看到的那样,您在两个服务之间使用共享资源 - 这是实体框架 DbContext。


我想一个线程正在初始化 DbContext,同时第二个线程正在使用相同的 DbContext。正如您从异常消息中看到的:


创建模型时不能使用上下文。如果在 OnModelCreating 方法中使用上下文,或者多个线程同时访问相同的上下文实例,则可能会引发此异常。请注意,不保证 DbContext 和相关类的实例成员是线程安全的。


更好的锁定是:


private object _lock = new object();


    public EnumConversionStatus GenerateRmsImportFiles(int submissionId)

            {

                lock (_lock)

                {

                    using (var client = new RMSConversionService.RMSConversionServiceClient())

                    {

                        var result = client.GenerateRmsImportFiles(submissionId);

                        client.Close();

                        return result;

                    }

                }

            }



    public EnumConversionStatus GenerateAirImportFiles(int submissionId)

            {

                lock (_lock)

                {

                    using (var client = new AIRConversionService.AirConversionServiceClient())

                    {

                        var result = client.GenerateAirImportFiles(submissionId);

                        return result;

                    }

                }

            }


查看完整回答
反对 回复 2021-07-31
  • 1 回答
  • 0 关注
  • 225 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信