3

.NET 4 C# 콘솔 응용 프로그램이 있습니다. IBM i에서 데이터를 가져와 인터넷 SQL Server로 전송합니다. 이 끝날 때까지 그것은 완벽하게 작동, 나는 다음과 같은 오류가 발생합니다 :ObjectDisposedException 처리되지 않았습니다 : 프로그램 끝에서 안전한 핸들 닫혔습니다

System.ObjectDisposedException was unhandled Message=Safe handle has been closed Source=mscorlib ObjectName="" StackTrace: at System.Runtime.InteropServices.SafeHandle.DangerousRelease() at System.Threading.RegisteredWaitHandleSafe.Finalize() InnerException:

내 프로그램 코드는 다음과 같습니다 콘솔에서

class Program 
{ 
    static void Main(string[] args) 
    { 
     System.Console.WriteLine("Begin: " + DateTime.Now.ToString()); 
     SystemCodeController sc = new SystemCodeController(); 
     sc.SyncSystemCodes(); 
     ParkingTicketController pt = new ParkingTicketController(); 
     pt.SyncParkingTickets(); 
     EmailHelper.SendSuccessEmail(); 
     System.Console.WriteLine("End: " + DateTime.Now.ToString()); 
    } 
} 

, 나는 시작 시간과 종료 시간을 참조하십시오. 그래서 마지막 줄이 처형된다는 것을 압니다. 내가 잊어야 할 것은 무엇인가?

업데이트 : Sync * 메소드는 IBM의 데이터를 오브젝트로 가져오고 엔티티 프레임 워크를 사용하여 레코드를 데이터베이스에 삽입합니다.

public void SyncParkingTickets() 
{ 
    ptr.ClearTable(); 
    ptr.InsertNewCitation(ibmI.GetAllCitations()); 
    ptr.SaveChanges(); 
} 

public void InsertNewCitation(IEnumerable<ParkingTicket> citations) 
{ 
    foreach (ParkingTicket citation in citations) 
    { 
     InsertNewCitation(citation); 
    } 
} 

public void InsertNewCitation(ParkingTicket citation) 
{ 
    db.AddToParkingTickets(citation); 
} 

public IEnumerable<ParkingTicket> GetAllCitations() 
{ 
    SystemCodeRepository scr = new SystemCodeRepository(); 

    // Create SQL statement 

    DataTable dt = new DataTable(); 
    using (iDB2Connection conn = new iDB2Connection(_connString)) 
    { 
     using (iDB2Command cmd = new iDB2Command(sb.ToString(), conn)) 
     { 
      conn.Open(); 
      using (iDB2DataAdapter da = new iDB2DataAdapter(cmd)) { da.Fill(dt); } 
      conn.Close(); 
     } 
    } 

    #region Fill object from DataTable 
    var citations = from i in dt.AsEnumerable() 
        select new ParkingTicket 
        { 
         // Fill object 
        }; 
    #endregion 

    return citations; 
} 

모든 방법은이 방법과 유사하게 작동합니다.

+0

은'동기화 *'통화의 가족은 어떻게해야합니까? 코드를 볼 수 있습니까? 나는 그 WaitHandle을 유출 할 것입니다. – user7116

+0

'WaitHandle'이 무엇인지 모르겠으므로 간접적으로 만 사용하고있을 것입니다. –

+0

나는 그것을 IBM 드라이버까지 추적 해왔다. 나는 이것을 반영하여 내 대답을 업데이트했다. – user7116

답변

7

데이터베이스 액세스 방법의 iDB2Connection 제품군을 사용할 때 약간의 오차가 Googling reveals some scattered reports입니다. 분명히 IBM은 닷넷 2.0 per this Connect article으로 바뀐 EventHandles의 .Net 1.1 처리에 의존하고 있습니다.

최신 드라이버 버전으로 업데이트하는 것만 보입니다 (S21917 서비스 팩 5.3 또는 SI37892 5.4 참고).


당신은 WaitHandle에 대한 SafeWaitHandleClose()를 호출하고 있습니까?

WaitHandle wh = ...; 

wh.SafeWaitHandle.Close(); // will throw ObjectDisposedException 

From MSDN :

When you assign a new value to the SafeWaitHandle property, the previous handle will be closed when the previous SafeWaitHandle object is collected. Do not manually close the handle, because this results in an ObjectDisposedException when the SafeWaitHandle attempts to close the handle.

+2

와우, 나쁜 구현입니다. 'Dispose' 메서드를 호출하면'ObjectDisposedException'이 발생합니다! – ordag

+0

@ordag : 실제로 ObjectDisposedException은 폐기 된 이벤트 핸들을 사용하는 다른 스레드의 코드에서 발생합니다! – user7116

+0

좋아요 ... 클라이언트 액세스를 위해 5.4가 아닌 5.3을 사용하고 있습니다. 어쨌든 최신 패치를 다운로드 중입니다. 나는 이것이 우리를 최신 iSeries Access 버전으로 빠르게 밀어 넣을 것이라고 생각합니다. 피타입니다. 한 번에 여러 버전의 드라이버를 설치할 수 없기 때문에 모든 프로젝트를 한 번에 업그레이드해야합니다. –

2

귀하의 유형은 무엇입니까 Disposable? 응용 프로그램을 종료하기 전에 모든 일회용 자원을 폐기하십시오.

+0

게시 후 처음 생각했습니다. 내 코드에 IDisposable이 없음을 확인했습니다. 그건 도움이되지 않았어. 나는 지금 내가 만지는 모든 물체가'.Dispose()'를 포함하고 있는지 확인하고있다. –

+0

@MikeWills : 'IDisposable'을 추가해도 마술처럼 'SafeHandle'사용 문제가 해결되지 않습니다. 'SafeHandle' 또는 파생 된 클래스의 사용법을 코드에서 조사해야합니다. WaitHandle과 관련된 일부 코드가 잘못된 것 같습니다. – user7116

+1

내가 위에서 말했듯이, 'WaitHandle'이 무엇인지 모르기 때문에 간접적으로 사용하고있을뿐입니다. –

0

나는 동등한 처지에있다. 문제는 SafeHandle.ReleaseHandleP/Invoke 전화가 걸려 전화가 걸려 왔는데 System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success)이라고 말하면서 처분 된 후 SafeHandle으로 무엇인가를하려고 시도하는 것입니다.

아니 자신의 SafeHandle 구현이 아닙니까? 그렇지 않으면 CriticalHandle을 대신 사용해 볼 수있었습니다.

+0

아니, 그런 식으로하지 않았습니다. 이것은 알려진 버그입니까? 있는 경우 해결 방법이 있습니까? 나는이 라이브를 구현할 때 문제가 발생하는 것을 싫어한다. –

+0

동일한 오류가 있습니다 (물론 다른 앱). 그러나 그것을 다시 본 후에 나는 틀렸다고 생각합니다. 위의 편집을 참조하십시오. – ordag