2013-03-10 9 views
0

Outlook 공유 사서함의 여러 폴더를 모니터링하는 WPF 응용 프로그램에서 작업하고 있습니다. ItemAdd 및 ItemRemove 이벤트 처리기를 Folder.Items 개체에 연결했습니다.Outlook 폴더 이벤트가 임의로 공유 사서함에서 작동하지 않습니다.

모든 것이 몇 분 동안 훌륭하게 작동합니다. 그러나 시간이 지남에 따라 이벤트 처리는 "멍청한"것처럼 보입니다. 일부 폴더는 추가 및 제거를 인식하고 다른 폴더는 제거를 보지만 다른 폴더는 모든 활동을 보지 못합니다. 나에게 그것은 이벤트 처리기가 가비지 수집되고있는 것 같지만 내 Items 객체는 클래스에있는 전역 변수로 선언되므로 GC'd가 될 수는 없다.

Outlook Folder.Items 이벤트에서주의해야 할 함정이 있습니까? 오래 전에 잘 작동하는 유사한 프로세스로 작동하는 이전의 간단한 응용 프로그램이 있습니다. 내 이전 앱과이 새로운 앱 사이에는 항목 이벤트 처리가 진행되는 한 본질적인 차이가 없습니다. 나는이 문제를 일으키는 것에 정말로 손해를보고 있습니다.

다음은 관련 코드입니다. 이 상황을 가져 오기 위해 내가하고있는 일은 Outlook 공유 사서함의 각 폴더에 해당 폴더의 내용 (MailItems)을 나타내는 "TicketView"UserControl이 만들어집니다. 이 TicketView는 0에서 수십 개의 MailItems까지 포함 할 수있는 간단한 ListBox입니다.

public partial class TicketView : UserControl 
    { 
     private Folder _thisFolder = null; 
     private TicketCollection _thisTicketColl = null; 
     private Items _thisItems = null; 

     public TicketView(Folder folder) 
     { 
      InitializeComponent(); 

      _thisTicketColl = this.FindResource("TicketCollection") as TicketCollection; 
      _thisFolder = folder; 
      _thisItems = folder.Items; 

      SetFolderEvents(); 
      Refresh(); 
     } 

     private void SetFolderEvents() 
     { 
      _thisItems.ItemAdd += new ItemsEvents_ItemAddEventHandler(delegate 
       { 
        Refresh(); 
       }); 

      _thisItems.ItemRemove += new ItemsEvents_ItemRemoveEventHandler(delegate 
       { 
        Refresh(); 
       }); 
     } 

     public void Refresh() 
     { 
      BackgroundWorker worker = new BackgroundWorker(); 

      worker.DoWork += new DoWorkEventHandler(delegate(object sender, DoWorkEventArgs e) 
      { 
       string[] fields = new string[] { "Subject", "SenderName", "SentOn", "EntryID" }; 
       var olTable = TicketMonitorStatics.GetOutlookTable(_thisFolder, fields, filter); 
       olTable.Sort("SentOn", true); 
       var refreshedList = new List<Ticket>(); 

       while (!olTable.EndOfTable) 
       { 
        var olRow = olTable.GetNextRow(); 
        refreshedList.Add(new Ticket 
        { 
         Subject = olRow["Subject"], 
         Sender = olRow["SenderName"], 
         SentOn = olRow["SentOn"], 
         EntryID = olRow["EntryID"] 
        }); 
       }; 
       e.Result = refreshedList; 
      }); 

      worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(delegate(object sender, RunWorkerCompletedEventArgs e) 
      { 
       var refreshedList = e.Result as List<Ticket>; 
       UpdateTicketList(refreshedList); 

       worker.Dispose(); 
      }); 

      worker.RunWorkerAsync(); 
     } 

     private void UpdateTicketList(List<Ticket> newList) 
     { 
      _thisTicketColl.Clear(); 

      foreach (Ticket t in newList) 
      { 
       _thisTicketColl.Add(t); 
      } 
     } 
    } 
} 

답변

1

Outlook 이벤트는 어떤 종류의 동기화에도 사용하면 안됩니다. UI 용도로만 사용하도록 설계되었으며 과부하가 걸리거나 네트워크 오류가 발생하는 경우 (온라인 상점을 사용하는 경우) 삭제 될 수 있습니다.

이벤트는 나중에보다는 오히려 빨리 실행해야한다는 힌트로만 사용할 수 있습니다.

IExchangeExportChanges MAPI 인터페이스 (C++ 또는 Delphi 만 해당)를 사용하여 동기화를 수행 할 수 있습니다. 이것은 캐시 된 폴더를 동기화하기 위해 Outlook에서 사용하는 것과 동일한 API입니다. C++이나 Delphi를 사용하지 않는 경우 Redemption과 해당 RDOFolderSynchronizer 객체 (http://www.dimastr.com/redemption/rdofoldersynchronizer.htm)를 사용할 수 있습니다.

+0

여기에있는 내용을 참고하겠습니다. ItemAdd 및 ItemRemove 이벤트 처리기를 지우고 5 분마다 (타이머 사용) 다시 설정하는 루틴을 시도했습니다. 이것은 _thisItems 객체 자체를 다시 설정할 때까지 작동하지 않습니다. 이벤트를 제거하고 null _thisItems를 다시 _thisItems = _thisFolder.Items로 설정 한 다음 이벤트를 다시 설정하십시오.이 경우 문제가 해결 된 것으로 보입니다. 나는 왜이 앱에서 일어난 일인지 이해하지 못한다. –

+0

네트워크에 문제가있는 경우 알림 채널이 재설정되면이 문제가 나타납니다. 다시 말하지만, MAPI 이벤트는 신뢰할 수 없으며 신뢰할 수 없습니다. –