2013-02-13 1 views
0

Outlook 2010 추가 기능을 개발하고 있습니다.크로스 스레드 작업 가져 오는 중 Outlook 추가 기능에서 예외가 발생했습니다.

메인 추가 기능 클래스는이 같은 비동기 작업을 시작하고 다른 형태에서 suscribe하는 정적 이벤트를 선언한다 :

 int ProcesadosArchivado = 0; 
     public delegate void OnFileArchivedDelegate (int NumFilesArchived, string NameArchived); 
     public static event OnFileArchivedDelegate OnFileArchivedEvent = delegate { }; 


     private void ThisAddIn_Startup(object sender, System.EventArgs e) 
     { 
      Thread hiloArchivado = new Thread(DoArchiveBackground); 
      hiloArchivado.Start(); 

     }  

     private void DoArchiveBackground() 
     { 

      try 
      {   
       Outlook.Application app = null; 
       Outlook._NameSpace ns = null; 
       Outlook.MailItem item = null; 
       //Outlook.MAPIFolder inboxFolder = null; 
       DateTime MyDateTime = DateTime.Now.AddMonths(-3); 
       app = new Outlook.Application(); 
       ns = app.GetNamespace("MAPI"); 
       ns.Logon(null, null, false, false);  

       Outlook.Stores store; 
       Outlook.MAPIFolder rootFolder = null; 
       store = Application.Session.Stores; 
       foreach (Outlook.Store storeClass in store.Session.Stores) 
       { 
        rootFolder = storeClass.GetRootFolder();  
       }  

       Outlook.MAPIFolder folder = rootFolder.Folders["ARCHIVAR"];  
       Outlook.MAPIFolder ArchivarFolder = ns.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox); 

       // inboxFolder = ns.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox); 


       for (int i = 1; i <= ArchivarFolder.Items.Count; i++) 
       { 
        try 
        { 

         item = (Microsoft.Office.Interop.Outlook.MailItem)ArchivarFolder.Items[i]; 
         ProcesadosArchivado += 1; 
         OnFileArchivedDelegate myEvent = OnFileArchivedEvent; 
         myEvent.Invoke(ProcesadosArchivado, item.Subject);       


        //Messate iteration 
        } 
        catch (Exception ex) 
        { 

         throw; 
        } 

       } 

      } 

      //Catch folder iteration 
      catch (Exception ex) 
      { 

       throw; 
      } 

     } 

가 그럼 난 다른 형태의 정적 이벤트에 suscribe 일부를 업데이트하려고 InvokeRequired 사용하여 컨트롤 및 대표 :

public partial class ArchiveForm : Form 
    { 
     private delegate void UpdateControlDelegate (Control control,string Property,string value); 

     public ArchiveForm() 
     { 
      InitializeComponent(); 
      this.Load += new EventHandler(ArchiveForm_Load); 
     } 



     void ArchiveForm_Load(object sender, EventArgs e) 
     { 
      ThisAddIn.OnFileArchivedEvent += new ThisAddIn.OnFileArchivedDelegate(ThisAddIn_OnFileArchivedEvent); 
     } 

     void ThisAddIn_OnFileArchivedEvent(int NumFilesArchived, string NameArchived) 
     { 
      updateControls(NumFilesArchived,NameArchived);   

     } 

     void UpdateControl(Control control,string Property,string value) 
     { 
      PropertyInfo prop = control.GetType().GetProperty("Text"); 

      prop.SetValue(control, 
         Convert.ChangeType(value, prop.PropertyType), null);   

     } 

    private void updateControls(int NumFilesArchived, string NameArchived) 
    {    

      if (lblArchivado.InvokeRequired) 
      { 
       UpdateControlDelegate del = new UpdateControlDelegate(UpdateControl); 
       //del.BeginInvoke(lblArchivado, "Text", "Archivados: " + NumFilesArchived.ToString(), null, null); 
       del.Invoke(lblArchivado, "Text", "Archivados: " + NumFilesArchived.ToString()); 
      } 
      else 
       this.lblArchivado.Text = "Archivados: " + NumFilesArchived.ToString(); 

      if (lblAsunto.InvokeRequired) 
      { 
       UpdateControlDelegate del = new UpdateControlDelegate(UpdateControl); 
       //del.BeginInvoke(lblAsunto, "Text", "Asunto: " + NameArchived, null, null); 
       del.Invoke(lblAsunto, "Text", "Asunto: " + NameArchived); 
      } 

      else 
       this.lblAsunto.Text = "Asunto: " + NameArchived; 

     } 


    } 

임 점점 크로스 헤드 잘못된 연산 예외,라인 도달시 :

* prop.SetValue (control, Convert.ChangeType (value, prop.PropertyType), null); *

나는이 예외를 받고있는 이유 정말 얻을 해달라고, 그래서 그것은 invoreRequired을 통해 얻고 대리자를 호출한다. 이에

del.Invoke(lblAsunto, "Text", "Asunto: " + NameArchived); 

:

답변

0

좋아, 몇 가지 조사를 수행 한 후 나는이 변경

this.Invoke(del, new object[] { lblAsunto, "Text", "Asunto: " + NameArchived }); 

을 그리고 지금 노력하고 있습니다.

0

보조 스레드에서 Outlook 개체 모델을 사용하면 안됩니다. 문제를 야기 할 수밖에 없다. OOM 개체가 반환 된 스레드와 다른 스레드에서 액세스되는 경우 Outlook 2013에서 즉시 예외가 발생합니다. 대부분의 경우 Outlook Migth의 이전 버전이 작동하지만 가장 불행한 순간에는 실패합니다.
위의 코드는 보조 스레드에서 Outlook.Application 개체의 새 인스턴스를 만듭니다. 그렇게 할 수는 있지만 모든 호출은 기본 Outlook 스레드에 마샬링되므로 보조 스레드를 사용하면 많은 도움이되지 않습니다.
유일한 해결 방법은 확장 MAPi (C++ 또는 Delphi) 또는 MAPI를 사용하는 래퍼 (예 : Redemption)를 사용하는 것입니다.

관련 문제