MattE
MattE

Reputation: 1114

WPF Task/Threading issues when trying to open Outlook Email

I have a WPF application that has a part where the users fill out basically an outlook-like form and then it populates an Outlook Email with the appropriate information. The problem is that while this email is open, code execution stops until the email is either sent or closed.

I am attempting to put it on a new thread but I am running into all kinds of problems in various places with getting this to work. The "body" of the email form is a rich text box and needs to be formatted prior to putting it into the Outlook email for it to show up properly.

From what I read the Clipboard calls must be put on their own STA threads, but then it returns null before they finish.

How can I get this working properly? Basically all I want is for the Outlook Email Item to be on its own thread so it doesn't block execution of the main thread while its open.

private async Task CreateEmail()
{

    try
   {
       //create an outlook object
       await Task.Run(() =>
     {
        MyOutlook.Application oApp = new MyOutlook.Application();

  //we need to check the to strings of that various items and join them together
        var toStrings = emailForm.ToMain;
        toStrings += String.IsNullOrEmpty(emailForm.ToRM) ? "" : ";" + emailForm.ToRM;
         toStrings += String.IsNullOrEmpty(emailForm.ToSM) ? "" : ";" + emailForm.ToSM;

         MyOutlook.MailItem oMailItem = (MyOutlook.MailItem)oApp.CreateItem(MyOutlook.OlItemType.olMailItem);
          oMailItem.To = toStrings;
          oMailItem.CC = emailForm.CC;
          oMailItem.BCC = emailForm.BCC;
          oMailItem.Subject = emailForm.Subject;
          oMailItem.RTFBody = GetRTBText();
          oMailItem.Display(true);
       });

      }
      catch(Exception ex)
     {
     ErrorWindow errWin = new ErrorWindow("There was an error creating the Outlook Email! Error: " + ex.Message);
     errWin.Show();
   }             
}

private byte[] GetRTBText() 
{

    byte[] RTFArr = null;
    //need to create a new STA Thread for the clipboard
    Thread thread = new Thread(() => Clipboard.Clear());

    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();
    thread.Join();
    this.Dispatcher.Invoke(() =>
    {
        RTBBody.SelectAll();
        RTBBody.Copy();                
    });
        Thread thread2 = new Thread(() => RTFArr = Encoding.UTF8.GetBytes  (Clipboard.GetText(TextDataFormat.Rtf)));
        thread2.SetApartmentState(ApartmentState.STA);
        thread2.Start();
        thread.Join();

    return RTFArr;
}

Upvotes: 0

Views: 131

Answers (1)

Dmitry Streblechenko
Dmitry Streblechenko

Reputation: 66255

Do not call Display(true) - that will display the message modally. Call Display(false).

Upvotes: 2

Related Questions