2010-06-29 3 views
2

업데이트 : Henk의 도움을 받아 공개 Dispose()가 호출되고 있으며, Dispose()가 Private Dispose (true)를 호출합니다. 이것은 IDisposable 인터페이스의 첫 번째 구현이므로 올바른지 확실하지 않습니다. Dispose를 명시 적으로 어디에도 호출하지 않습니다. WCF 아키텍처는 각 OperationContract 멤버를 종료 할 때이를 호출하는 것 같습니다.정적 데이터가 포함 된 WCF 서비스에 문제가 있음

비 관리 클린업 코드를 지금 Dispose에서 제거하고 여러 호출이 정적 데이터에 액세스 할 수 있습니다. 정적 저장소에 개체에 대한 참조가있는 경우에도 Dispose()는 호출로부터 반환 될 때 로컬로 할당 된 모든 개체에 대해 호출됩니다. net에서 IDisposable 인터페이스가 올바르게 호출되도록이 문제를 해결하는 방법을 잘 모릅니다. 나는이 객체들이 어떤 시점에서 가비지 컬렉션을 얻을 것이라고 추측한다. 폐기가 호출 될 때 여기에

는 첫번째 호출에서 반환에 호출 스택입니다!

BossISeriesCwbxService.dll BossISeriesCwbxServices.DataContracts.ISeriesSystem.Dispose (부울 bDisposing = TRUE) 라인 119 C#
BossISeriesCwbxService.dll! BossISeriesCwbxServices.DataContracts.ISeriesSystem.Dispose() 라인 (107) + 0xd는 C#
바이트하여 System.ServiceModel.dll! System.ServiceModel.Dispatcher.MessageRpc.DisposeParametersCore() + 0x56 바이트 SYSTE m.ServiceModel.dll! System.ServiceModel.Dispatcher.MessageRpc.DisposeParameters() + 0xF입니다 바이트하여 System.ServiceModel.dll! System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessageCleanup (REF System.ServiceModel.Dispatcher.MessageRpc RPC = System.ServiceModel.Dispatcher.MessageRpc {}) + 0x135 바이트하여 System.ServiceModel.dll! System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5 (REF System.ServiceModel.Dispatcher.MessageRpc RPC = { System.ServiceModel.Dispatcher. MessageRpc}) + 0x1bf bytes System.ServiceModel.dll! System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4 (ref System.ServiceModel.Dispatcher.MessageRpc RPC) + 0x80으로 바이트
하여 System.ServiceModel.dll! System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3 (REF System.ServiceModel.Dispatcher.MessageRpc RPC) + 0x36 바이트
하여 System.ServiceModel.dll!는 system.serviceModel .Dispatcher.ImmutableDispatchRuntime.ProcessMessage2 (REF System.ServiceModel.Dispatcher.MessageRpc RPC) + 0x43부터 바이트
하여 System.ServiceModel.dll! System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1 (REF System.ServiceModel.Dispatcher.MessageRpc rpc) + 0xd7 bytes
System.ServiceModel.dll! System.Serv iceModel.Dispatcher.MessageRpc.Process (BOOL isOperationContextSet = 거짓) + 0x9b 바이트
하여 System.ServiceModel.dll! System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.Dispatch (REF System.ServiceModel.Dispatcher.MessageRpc RPC, BOOL isOperationContextSet) +

하여 System.ServiceModel.dll! System.ServiceModel.Dispatcher.ChannelHandler.DispatchAndReleasePump (System.ServiceModel.Channels.RequestContext 요청 = {System.ServiceModel.Security.SecuritySessionServerSettings 바이트 0x2d.SecuritySessionRequestContext}, 부울 cleanThread, System.ServiceModel.OperationContext currentOperationContext) + 0x20c 바이트
하여 System.ServiceModel.dll! System.ServiceModel.Dispatcher.ChannelHandler.HandleRequest (System.ServiceModel.Channels.RequestContext 요청, 시스템 .ServiceModel.OperationContext currentOperationContext) + 0xDF를 바이트

하여 System.ServiceModel.dll! System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump (System.IAsyncResult 결과) + 0x43부터 바이트
하여 System.ServiceModel.dll! System.Ser viceModel.Dispatcher.ChannelHandler.OnContinueAsyncReceive (객체 상태) + 0x45 바이트
하여 System.ServiceModel.dll! System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.Invoke2() +부터 0x46 바이트하여 System.ServiceModel.dll! 시스템. ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.OnSecurityContextCallback (객체 O) +하는 0x28 바이트
가 mscorlib.dll! System.Security.SecurityContext.Run (System.Security.SecurityContext SecurityContext에, System.Threading.ContextCallback 콜백 개체 상태) + 0x55 바이트

System.ServiceModel.dll! System.ServiceModel.Cha nnels.IOThreadScheduler.CriticalHelper.WorkItem.Invoke() +

바이트에는 0x4d하여 System.ServiceModel.dll! System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.ProcessCallbacks() + 0x180 바이트하여 System.ServiceModel.dll! 시스템. ServiceModel.Channels.IOThreadScheduler.CriticalHelper.CompletionCallback (객체 상태) +
하여 System.ServiceModel.dll! System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.ScheduledOverlapped.IOCallback (단위 의 errorCode, UINT하는 numBytes 바이트 0x7a, 하여 System.Threading .NativeOverlapped * nativeOverlapped) + 0xf 바이트
SMDiagnostics.dll! System.Serv iceModel.Diagnostics.Utility.IOCompletionThunk.UnhandledExceptionFrame (단위 오류, UINT의 bytesRead, System.Threading.NativeOverlapped * nativeOverlapped)
가 mscorlib.dll 바이트 0x3d +! System.Threading._IOCompletionCallback.PerformIOCompletionCallback (단위 의 errorCode, UINT하는 numBytes , System.Threading.NativeOverlapped * pOVERLAP) + 0x54 바이트

나는 WCF 서비스의 구현 클래스에서 정적 데이터를 캐시에 대한 몇 가지 게시물을 읽고, A의 개체에 대한 처리 호출 GC에 문제가 있었다 정적 사전. IBM iSeries Access에서 일부 activex 객체를 참조하므로 IDisposable 인터페이스를 구현하여 iSeries에 대한 연결을 정리했습니다. 내 문제는 GC가 서비스 클래스의 정적 멤버에 개체를 삭제하는 것입니다. 모든 코드가 필요하다는 것은 확실하지 않지만, 어쨌든 여기에 있습니다. 문제는 각 OperationContract 메서드에서 반환 할 때 GC가 관련된 Dictionary에 추가 된 ISeriesSystem 또는 Queue 개체에서 Dispose를 호출하지만 ISeriesSystem Dictionary는 정적이므로 개체에 대한 참조를 보유하고 있다고 생각합니다. GC는 사전에서 제거 될 때까지 수행되지 않습니다.

서비스 인터페이스 :

[ServiceContract(Namespace="BossISeriesCwbxServices")] 
public interface IDataQueueService 
{ 
    [OperationContract] 
    ISeriesSystem SystemInitialize(string sISeriesName); 

    [OperationContract(Name="FinalizeSystemByName")] 
    void SystemFinalize(string sISeriesName); 

    [OperationContract] 
    void SystemFinalize(ISeriesSystem oISeriesSystem); 

    [OperationContract] 
    Queue QueueInitialize(string sQueueName, string sLibrary, string sISeriesName); 

    [OperationContract(Name="FinalizeQueueByName")] 
    void QueueFinalize(string sQueueName, string sLibrary, string sISeriesName); 

    [OperationContract] 
    void QueueFinalize(Queue oDataQueue); 

    [OperationContract (Name="QueueWriteByName")] 
    void QueueWrite(string sQueueName, string sLibrary, string sISeriesName, string sMessage); 

    [OperationContract] 
    void QueueWrite(Queue oDataQueue, string sMessage); 

    [OperationContract (Name="QueueReadByName")] 
    string QueueRead(string sQueueName, string sLibrary, string sISeriesName); 

    [OperationContract] 
    string QueueRead(Queue oDataQueue);  
} 

서비스 구현 :

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)] 
public class DataQueueService : IDataQueueService 
{ 
    private static Dictionary<string, ISeriesSystem> mdictISeriesSystems = new Dictionary<string, ISeriesSystem>(); 
    public static IDictionary<string, ISeriesSystem> ISeriesDict 
    { 
     get { return mdictISeriesSystems; } 
    } 

    public ISeriesSystem SystemInitialize(string sISeriesName) 
    { 
    ISeriesSystem oISeriesSystem = AddSystem(sISeriesName); 
    return oISeriesSystem; 
    } 

    public void SystemFinalize(string sISeriesName) 
    { 
    } 

    public void SystemFinalize(ISeriesSystem oISeriesSystem) 
    { 
    SystemFinalize(oISeriesSystem.Name); 
    } 


    public Queue QueueInitialize(string sQueueName, string sLibrary, string sISeriesName) 
    { 
    ISeriesSystem oISeriesSystem = null; 
    Queue oDataQueue = null; 

    try 
    { 
     oISeriesSystem = AddSystem(sISeriesName); 
     oDataQueue = oISeriesSystem.AddQueue(sQueueName, sLibrary); 
    } 
    catch (Exception ex) 
    { 
     // ToDo: Log ex to WCF service log and remove from Console. 
     Console.WriteLine(ex.ToString()); 
     oDataQueue = null; 
    } 

    return oDataQueue; 
    } 

    public Queue QueueInitialize(string sQueueName, string sLibrary, ISeriesSystem oISeriesSystem) 
    { 
    return QueueInitialize(sQueueName, sLibrary, oISeriesSystem.Name); 
    } 

    public void QueueFinalize(string sQueueName, string sLibrary, string sISeriesName) 
    { 
    string sISeriesKey = sISeriesName.Trim(); 
    string sDataQueueKey = sLibrary.Trim() + sQueueName.Trim(); 

    ISeriesSystem oISeriesSystem = null; 
    Queue oDataQueue = null; 


    if (DataQueueService.ISeriesDict.TryGetValue(sISeriesKey, out oISeriesSystem)) 
    { 
     if (oISeriesSystem.DataQueueDict.TryGetValue(sDataQueueKey, out oDataQueue)) 
     { 
      oDataQueue.Dispose(); 
      oDataQueue = null; 
      oISeriesSystem.DataQueueDict.Remove(sDataQueueKey); 
     } 

     if (oISeriesSystem.DataQueueDict.Count == 0) 
     { 
      oISeriesSystem.Dispose(); 
      oISeriesSystem = null; 
     } 
    } 
    } 

    public void QueueFinalize(Queue oDataQueue) 
    { 
    QueueFinalize(oDataQueue.Name, oDataQueue.Library, oDataQueue.ISeriesName); 
    } 

    public void QueueWrite(string sQueueName, string sLibrary, string sISeriesName, string sMessage) 
    { 
    string sISeriesKey = sISeriesName.Trim(); 
    string sDataQueueKey = sLibrary.Trim() + sQueueName.Trim(); 

    ISeriesSystem oISeriesSystem = null; 
    Queue oDataQueue = null; 


    if (DataQueueService.ISeriesDict.TryGetValue(sISeriesKey, out oISeriesSystem)) 
    { 
     if (oISeriesSystem.DataQueueDict.TryGetValue(sDataQueueKey, out oDataQueue)) 
     { 
      oDataQueue.Write(sMessage); 
     } 
    } 
    } 

    public void QueueWrite(Queue oDataQueue, string sMessage) 
    { 
    QueueWrite(oDataQueue.Name, oDataQueue.Library, oDataQueue.ISeriesName, sMessage); 
    } 

    public string QueueRead(string sQueueName, string sLibrary, string sISeriesName) 
    { 
    string sISeriesKey = sISeriesName.Trim(); 
    string sDataQueueKey = sLibrary.Trim() + sQueueName.Trim(); 

    ISeriesSystem oISeriesSystem = null; 
    Queue oDataQueue = null; 


    if (DataQueueService.ISeriesDict.TryGetValue(sISeriesKey, out oISeriesSystem)) 
    { 
     if (oISeriesSystem.DataQueueDict.TryGetValue(sDataQueueKey, out oDataQueue)) 
     { 
      return oDataQueue.Read(); 
     } 
    } 

    return ""; 
    } 

    public string QueueRead(Queue oDataQueue) 
    { 
    return QueueRead(oDataQueue.Name, oDataQueue.Library, oDataQueue.ISeriesName); 

    } 

    ISeriesSystem AddSystem(string sISeriesName) 
    { 
    ISeriesSystem oISeriesSystem = null; 
    string sISeriesKey = sISeriesName.Trim(); 

    if (!DataQueueService.ISeriesDict.TryGetValue(sISeriesKey, out oISeriesSystem)) 
    { 
     oISeriesSystem = new ISeriesSystem(sISeriesName); 
     DataQueueService.ISeriesDict[sISeriesKey] = oISeriesSystem; 
    } 

    return oISeriesSystem; 
    } 

ISeriesSystem DataContract :

using System; 
using System.Collections.Generic; 
using System.Text; 

using System.ServiceModel; 
using System.Runtime.Serialization; 

using cwbx; 

namespace BossISeriesCwbxServices.DataContracts 
{ 
    public class ISeriesSystem : IDisposable 
    { 

     private string msName; 
     [DataMember] 
     public string Name 
     { 
     get { return msName; } 
     set { msName = value; } 
     } 

     private Dictionary<string, Queue> mdictDataQueues = new Dictionary<string, Queue>(); 
     public IDictionary<string, Queue> DataQueueDict 
     { 
     get { return mdictDataQueues; } 
     } 

     private cwbx.AS400System mcwbxISeriesSystem = new AS400System(); 
     private cwbx.AS400System CwbxISeriesSystem 
     { 
     get { return mcwbxISeriesSystem; } 
     set { mcwbxISeriesSystem = value; } 
     } 


     private bool bDisposed = false; 


     public ISeriesSystem() 
     { 

     } 

     public ISeriesSystem(string sISeriesName) 
     { 
     try 
     { 
      // Set DataContract properties. 
      this.Name = sISeriesName; 

      // Connect to iSeries, Logon and connect to iSeries services that may be used. 
      this.CwbxISeriesSystem.Define(sISeriesName); 
      this.CwbxISeriesSystem.UserID = "APP1DAK"; 
      this.CwbxISeriesSystem.Password = "DONNA99"; 
      this.CwbxISeriesSystem.Signon(); 
      this.CwbxISeriesSystem.Connect(cwbcoServiceEnum.cwbcoServiceDataQueues); 
      this.CwbxISeriesSystem.Connect(cwbcoServiceEnum.cwbcoServiceSecurity); 
      this.CwbxISeriesSystem.Connect(cwbcoServiceEnum.cwbcoServiceRemoteCmd); 
     } 
     catch (Exception ex) 
     { 
      // ToDo: Log ex to WCF service log and remove from Console. 
      Console.WriteLine(ex.ToString()); 
      foreach (cwbx.Error cwbxError in this.CwbxISeriesSystem.Errors) 
      { 
       Console.WriteLine(cwbxError.Text); 
       Console.WriteLine(cwbxError.ToString()); 
      } 
     } 
     } 

     ~ISeriesSystem() 
     { 
     Dispose(false); 
     } 

     public void Dispose() 
     { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
     } 

     private void Dispose(bool bDisposing) 
     { 
     // Only Dispose of the object 1 time. 
     if (!this.bDisposed) 
     { 
      // If disposing equals true, Dispose() was called by GC, so dispose all managed resources. 
      if (bDisposing) 
      { 
       // Dispose managed resources, calling object Dispose method for objects 
       // that implement IDisposable interface. 
      } 

      try 
      { 
       if (this.CwbxISeriesSystem.IsConnected(cwbcoServiceEnum.cwbcoServiceAny) == 1) 
       { 
        this.CwbxISeriesSystem.Disconnect(cwbcoServiceEnum.cwbcoServiceAll); 
       } 
      } 
      catch (Exception ex) 
      { 
       // ToDo: Log ex to WCF service log and remove from Console. 
       Console.WriteLine(ex.ToString()); 
       foreach (cwbx.Error cwbxError in this.CwbxISeriesSystem.Errors) 
       { 
        Console.WriteLine(cwbxError.Text); 
        Console.WriteLine(cwbxError.ToString()); 
       } 
      } 

      // Mark disposing as being done. 
      bDisposed = true; 
     } 
     } 

     public Queue AddQueue(string sQueueName, string sLibrary) 
     { 
     Queue oDataQueue = null; 
     string sDataQueueKey = sLibrary.Trim() + sQueueName.Trim(); 

     if (!this.DataQueueDict.TryGetValue(sDataQueueKey, out oDataQueue)) 
     { 
      oDataQueue = new Queue(sQueueName, sLibrary, this.CwbxISeriesSystem); 
      this.DataQueueDict[sDataQueueKey] = oDataQueue; 
     } 

     return oDataQueue; 
     } 
    } 
} 

큐 DataContract :

using System; 
using System.Collections.Generic; 
using System.Text; 

using System.ServiceModel; 
using System.Runtime.Serialization; 

using cwbx; 

namespace BossISeriesCwbxServices.DataContracts 
{ 
    [DataContract] 
    public class Queue : IDisposable 
    { 
     private string msName; 
     [DataMember] 
     public string Name 
     { 
     get { return msName; } 
     set { msName = value; } 
     } 

     private string msLibrary; 
     [DataMember] 
     public string Library 
     { 
     get { return msLibrary; } 
     set { msLibrary = value; } 
     } 

     private string msISeriesName; 
     [DataMember] 
     public string ISeriesName 
     { 
     get { return msISeriesName; } 
     set { msISeriesName = value; } 
     } 

     private short miWaitTime = 10; 
     [DataMember] 
     public short WaitTime 
     { 
     get { return miWaitTime; } 
     set { miWaitTime = value; } 
     } 

     private short miNumberOfAttempts = 1; 
     [DataMember] 
     public short NumberOfAttempts 
     { 
     get { return miNumberOfAttempts; } 
     set { miNumberOfAttempts = value; } 
     } 

     private short miMaxQueueIndex = 1; 
     public short MaxQueueIndex 
     { 
     get { return miMaxQueueIndex; } 
     set { miMaxQueueIndex = value; } 
     } 

     private short miCurrentQueueIndex = 1; 
     public short CurrentQueueIndex 
     { 
     get { return miCurrentQueueIndex; } 
     set { miCurrentQueueIndex = value; } 
     } 



     private cwbx.DataQueue mcwbxDataQueue = new cwbx.DataQueue(); 
     private cwbx.DataQueue CwbxDataQueue 
     { 
     get { return mcwbxDataQueue; } 
     set { mcwbxDataQueue = value; } 
     } 

     private bool bDisposed = false; 


     public Queue() 
     { 
     } 

     public Queue(string sQueueName, string sLibrary, cwbx.AS400System cwbxISeriesSystem) 
     { 
     this.Name = sQueueName; 
     this.Library = sLibrary; 
     this.ISeriesName = cwbxISeriesSystem.SystemName; 

     this.CwbxDataQueue.QueueName = sQueueName; 
     this.CwbxDataQueue.LibraryName = sLibrary; 
     this.CwbxDataQueue.system = cwbxISeriesSystem; 
     } 

     ~Queue() 
     { 
     Dispose(false); 
     } 

     public void Dispose() 
     { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
     } 

     private void Dispose(bool bDisposing) 
     { 
     // Only Dispose of the object 1 time. 
     if (!this.bDisposed) 
     { 
      // If disposing equals true, Dispose() was called by GC, so dispose all managed resources. 
      if (bDisposing) 
      { 
       // Dispose managed resources, calling object Dispose method for objects 
       // that implement IDisposable interface. 
      } 

      // Call the appropriate methods to clean up unmanaged resources here. 
      try 
      { 
       this.CwbxDataQueue = null; 
      } 
      catch (Exception ex) 
      { 
       // ToDo: Log ex to WCF service log and remove from Console. 
       Console.WriteLine(ex.ToString()); 
       foreach (cwbx.Error cwbxError in this.CwbxDataQueue.Errors) 
       { 
        Console.WriteLine(cwbxError.Text); 
        Console.WriteLine(cwbxError.ToString()); 
       } 
      } 
      // Mark disposing as being done. 
      bDisposed = true; 
     } 
     } 


     public void Write(string sMessage) 
     { 
     try 
     { 
      cwbx.StringConverter cwbxStringConverter = new cwbx.StringConverter(); 
      Object oBytes = cwbxStringConverter.ToBytes(sMessage); 
      this.CwbxDataQueue.Write(oBytes, false); 
     } 
     catch (Exception ex) 
     { 
      // ToDo: Log ex to WCF service log and remove from Console. 
      Console.WriteLine(ex.ToString()); 
      foreach (cwbx.Error cwbxError in this.CwbxDataQueue.Errors) 
      { 
       Console.WriteLine(cwbxError.Text); 
       Console.WriteLine(cwbxError.ToString()); 
      } 
     } 
     } 

     public string Read() 
     { 
     try 
     { 
      Object oObject = null; 
      return (new cwbx.StringConverter()).FromBytes(this.CwbxDataQueue.Read(this.WaitTime * this.NumberOfAttempts, out oObject)); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.ToString()); 
      foreach (cwbx.Error cwbxError in this.CwbxDataQueue.Errors) 
      { 
       Console.WriteLine(cwbxError.Text); 
       Console.WriteLine(cwbxError.ToString()); 
      } 

      return ""; 
     } 
     } 
    } 
} 

클라이언트 코드 :

ISeriesSystem oISeriesSystem = null; 
Queue oDataQueue = null; 

oISeriesSystem = DQService.SystemInitialize("A2029D2.AS400.US.UPS.COM"); 
oDataQueue = DQService.QueueInitialize("SMTLST020", "IB5EXE", oISeriesSystem.Name); 
oISeriesSystem.DataQueueDict.Add(oDataQueue.Library + oDataQueue.Name, oDataQueue); 
ISeriesSystemDict.Add(oISeriesSystem.Name, oISeriesSystem); 

DQService.QueueWrite(oDataQueue, "Testing cwbx.DataQueue WCF service"); 
string sMessage = DQService.QueueRead(oDataQueue); 

의 exe 호스팅 서비스 :

Uri baseAddress = new Uri("http://localhost:8080/BossISeriesCwbxServices"); 

//Instantiate new ServiceHost 
moServiceHost = new ServiceHost(typeof(BossISeriesCwbxServices.DataQueueService), baseAddress); 

// Add Endpoint 
moServiceHost.AddServiceEndpoint(typeof(BossISeriesCwbxServices.IDataQueueService), new WSHttpBinding(), "IDataQueueService"); 
// Enable metadata exchange. 
ServiceMetadataBehavior smb = new ServiceMetadataBehavior(); 
smb.HttpGetEnabled = true; 
moServiceHost.Description.Behaviors.Add(smb); 

//Open moServiceHost 
moServiceHost.Open(); 
Console.WriteLine("The IDataQueueService is ready."); 
Console.WriteLine("Press <ENTER> to terminate service."); 
Console.WriteLine(); 

답변

0

는 다음과 같은 코드를 넣어 수 : 단지 확인하기 위해 서비스 계약에

[ServiceContract(SessionMode = SessionMode.Required)] 

확실 전송 세션이 창조되고 있는가? 그렇지 않으면 오류가 발생합니다.

WSHttpBinding 보안 및 안정적인 세션없이 전송 세션을 만들지 않습니다.

편집 : 그것보다

다른 당신이 Single Instance 서비스를 생성하기 때문에, 당신은 왜 정적 멤버를 필요? 인스턴스가 하나만 생기므로 인스턴스의 모든 인스턴스 멤버가 인스턴스와 함께 살며 정적이됩니다. 그것에 대해 생각해 보셨습니까? 아니면 정적 멤버를 사용하는 특별한 이유가 있습니까?

+0

SessionMode와 동일한 동작입니다.필수 사항. 나는 Http 바인딩에 묶여 있지 않다. 이것이 생산에 들어간다면 실제로 NetTcp를 사용할 것입니다. –

1

정기적으로 또는 때마다 발생합니까? 개발 중이거나 프로덕션 서버에서만 (얼마 후) 발생합니까?

IIS에서이 프로그램을 호스트하면 서버가 앱을 '재활용'하기로 결정할 수 있습니다. 기본 조언 : 서버 응용 프로그램에서 static을 사용하지 마십시오. 그것은 신뢰성이없고 확장 성이 없습니다.


편집
OK, 나는 조금 더 (전부는 아니지만) 읽었습니다.

문제는 각 OperationContract를 메소드로부터 반환에, GC 이

당신은 훌륭한 세부 사항에서 다음을 확인해야 ISeriesSystem 또는 대기열 개체에서 폐기 촉구한다는 것입니다. 파이널 라이저 (일명 소멸자)를 호출하는 GC입니까? 로깅 또는 디버깅을 사용하여 과부하 Dispose (false)가 호출되는지 확인해야합니다. Dispose (true)가 호출되면 (실제로 많은 코드가 포함 된 것을 볼 수 있습니다) 실제 원인을 스택 추적해야합니다.

+0

프로덕션 환경이 아닌 개념 증명 서비스입니다. 정적 사전에 추가되는 모든 호출에서 발생합니다. –

+0

Dispose (true)는 –

+0

스택 추적이라고합니다. (전체 스택을 붙여 넣을 수는 없습니다) > BossISeriesCwbxServices.DataContracts.ISeriesSystem.Dispose() Line 107 C# System.ServiceModel.dll! System.ServiceModel. Dispatcher.MessageRpc.DisposeParametersCore() + 0x56 bytes System.ServiceModel.Dispatcher.MessageRpc.DisposeParameters() + 0xf bytes –

0

조금 늦었지만 [OperationBehavior(AutoDisposeParameters = false)] 속성을 추가하려 했습니까?

Link to MSDN Forum

관련 문제