2013-03-10 3 views
0

Je travaille sur une application WPF qui surveille de nombreux dossiers dans une boîte aux lettres partagée Outlook. J'ai câblé les gestionnaires d'événements ItemAdd et ItemRemove à un objet Folder.Items.Les événements du dossier Outlook cessent de fonctionner de manière aléatoire sur la boîte aux lettres partagée

Tout fonctionne très bien pendant quelques minutes. Mais au fur et à mesure que le temps passe, la manipulation de l'événement semble aller "poof". Certains dossiers reconnaîtront toujours l'ajout et la suppression, d'autres ne verront que les supprimés, alors que d'autres ne verront aucune activité. Pour moi, il semble que les gestionnaires d'événements soient collectés, mais mon objet Items est déclaré comme une variable globale dans la classe où il se trouve, donc je ne vois pas comment ils pourraient être éliminés.

Y at-il des pièges que je devrais être au courant avec Outlook Folder.Items événements? J'ai une application précédente, plus simple qui fonctionne par des processus similaires qui fonctionne bien pendant des périodes de temps prolongées. Il n'y a pas de différence intrinsèque, en ce qui concerne la gestion des événements Item, entre mon ancienne application et cette nouvelle. Je ne sais vraiment pas ce qui cause ça.

Ci-dessous le code correspondant. Pour apporter un contexte à ceci, ce que je fais est, pour chaque dossier dans la boîte aux lettres partagée par Outlook un UserControl de «TicketView» est créé qui représente le contenu (MailItems) de ce dossier. Ce TicketView est un simple ListBox qui peut contenir entre 0 et quelques dizaines de MailItems - rien d'excessif.

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); 
      } 
     } 
    } 
} 

Répondre

1

Les événements Outlook ne doivent pas être utilisés pour n'importe quel type de synchronisation. Ils sont conçus pour être utilisés uniquement à des fins d'interface utilisateur et peuvent être supprimés en cas de charge importante ou en cas d'erreur réseau (si vous utilisez un magasin en ligne).

Vous pouvez utiliser des événements uniquement comme indication que votre code doit être exécuté plus tôt que plus tard.

Vous pouvez utiliser l'interface MAPI IExchangeExportChanges (C++ ou Delphi uniquement) pour effectuer la synchronisation; C'est la même API utilisée par Outlook pour synchroniser ses dossiers en cache. Si vous n'utilisez pas C++ ou Delphi, vous pouvez utiliser Redemption et son objet RDOFolderSynchronizer (http://www.dimastr.com/redemption/rdofoldersynchronizer.htm)

+0

Je vais prendre cela en délibéré mais ce n'est pas ce qui se passe ici. J'ai essayé une routine pour effacer les gestionnaires d'événements ItemAdd et ItemRemove, puis les réinitialiser toutes les 5 minutes (avec un minuteur). Cela ne fonctionnait pas non plus jusqu'à ce que je réinitialise l'objet _thisItems lui-même. Je supprime les événements, null _thisItems, le redéfinit sur _thisItems = _thisFolder.Items, puis ré-configure les événements - cela semble avoir corrigé le problème. Je ne comprends tout simplement pas pourquoi cela se passe dans cette application et pas mon autre. –

+0

S'il y a un problème de réseau, le canal de notification est réinitialisé, vous voyez ce problème. Encore une fois, les événements MAPI ne sont pas fiables et vous ne pouvez pas les rendre fiables. –

Questions connexes