2017-05-10 19 views
1

RDO 5.14를 사용하여 Exchange 2000에서 내 회사의 상당히 큰 공용 폴더 레이아웃 (폴더 수 000 개)의 내용을 내보내려고합니다.RDO/MAPI를 사용하여 대용량 공용 폴더 저장소를 추출하고 E_MAPI_TOO_BIG를 가져 오는 중

나는 Exchange 사용자가 Exchange 저장소 제한 인 documented here을 위반했기 때문에 Exchange 2010에서 E_MAPI_TOO_BIG 오류를 제공한다는 점에서 많은 사람들이 발견 한 문제에 부딪힙니다.

많은 경우에 허용되는 솔루션은 더 많은 항목의 처리를 할 수 있도록 표시 않지만 여전히 날에 500 개 이상의 메시지를받을 수 없습니다 가끔 모든 심판에 while (Marshal.ReleaseComObject(ref)>0)GC.Collect()를 호출하는 것입니다.

일부 코드를 가지고 노는 중입니다. 그것은 놀랍게도 (적어도 나에게) 사실을 드러낸다. 나는 어떤 시점에서이 코드 샘플을 사용하는 경우는 다른 폴더에 액세스하려고 다른 코드에서 (실패,

for (int i = 1; i < items.Count; ++i) { 
    IRDOMail item = items.Item(i); 
    string SUCCESS = item.EntryID; 
} 

하지만 :이 같은 폴더에있는 항목을 반복하면

이 아무 문제가 없다) with E_MAPI_TOO_BIG :

for (int i = 1; i < items.Count; ++i) { 
    IRDOMail item = items.Item(i); 
    string FAIL = item.Subject; 
} 

이 시점에서 필자는 COM 기술의 한계에 도달했습니다. .NET InterOp에서 MailItem의 COM 속성을 참조 해제하는 일부 작업을 끝내면 내가 풀어 낼 수없는 참조를 얻게됩니다. 그렇다면 내가 어떻게 고칠 수 있을지 모르겠다.

RDO없이 MAPI를 사용하면 MAPI (14.0)의 특이한 점을 더 시사하면 비슷한 (그러나 다른) 동작을 볼 수 있습니까?

답변

1

이는 프로그램 구조와 문제가 아니라 RDO 또는 MAPI 중 하나와 직접 문제가 될 밝혀졌다. 특히이 문제는 전체 트리 항목을 반복적으로 처리하려고합니다.

폴더에서 MAPI/RDO MailItem의 모든 속성에 액세스하면 해당 폴더에서 항목에 대한 내부 참조가 만들어집니다. 비록 이것이 사실인지 또는 그것을 검증하는 방법을 확신 할 수는 없지만.

따라서 하나의 하위 브랜치 (하나의 폴더뿐만 아니라)에 500 개가 넘는 메시지가 있으면 E_MAPI_TOO_BIG가 설명 된 방식으로 구조를 '방문'하려고합니다.

그런 다음 솔루션은 재귀를 사용하여 폴더 EntryId의 목록을 만든 다음 GetFolderFromId()을 사용하여 해당 목록을 반복하여 폴더를 가져온 다음 항목을 반복합니다. 지금까지 내가 찾은 MAPI/RDO 프로그래밍 리소스에는이 사실이 언급되어 있지 않습니다.

UPDATE

관리 코드에서 작업 MAPI를 얻으려고 더 많은 시간을 보내고 난 후에 나는 그것을 시도하고 내가 시도하는 것을 할 수있는 근본적으로 나쁜 생각 결론에 도달했습니다. 위의 해결 방법이 조금 더 나아졌지만 메시지의 더 많은 속성에 액세스하려고 시도했을 때 같은 오류가 발생하여 궁극적으로 다시 실패했습니다.

뒤늦은 지경에이 문제는 아주 근본적으로 작동하며 많은 사람들이 그걸 처리 할 수있는 것으로 보이므로이를 입증하는 많은 리소스가 온라인에 있습니다. 그러나 관리 코드로 MAPI를 수행하는 것은 Microsoft에서 지원하지 않기 때문에 시작하기가 불안정한 것으로 보입니다. 이것은 직접 MAPI가 아닌 COM Interop 인 경우에도 마찬가지입니다.

Exchange와 함께 대규모 작업을 수행하려면 다른 Exchange 기술 중 하나를 사용해야합니다. 나는 완전하고 더 중요하게, 신뢰성있는 EWS를 사용하여 끝냈다. 이 사람이 도움이되기를 바랍니다!

+0

참고 문헌을 매달기에 특히주의해야하며, 여러 점 표기법을 사용하지 않는 것이 좋습니다. –

0

당신은 ReleaseComObject를 사용해야합니다 :

for (int i = 1; i < items.Count; ++i) { 
    IRDOMail item = items.Item(i); 
    string FAIL = item.Subject; 
    Marshal.ReleaseComObject(item); 
} 
+0

이것은 어떤 차이도없는 것처럼 보입니다. 아마도 범위를 벗어나는 '항목'은 참조를 해제하기에 충분할 것입니까? 나는 Marshal.ReleaseComObject()를 추가하는 것이 좋습니다 그물에 여러 참조를 찾았지만 필요하다고 생각할 수있는 유일한 시간은 레퍼런스가 지나치게 길게 머물러있는 것입니다. 정확한 사건이 아닙니다. –