アプリケーションがビジー/応答なし/ブレークポイントで一時停止している場合、メール受信イベント ハンドラーが返されてから長い時間が経っていても、Outlook が停止するという問題があります。
小さなテストケースをまとめました:
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Office.Interop.Outlook;
namespace OutlookPerfTest
{
class Program
{
private static Application app;
private static NameSpace ns;
static void Main(string[] args)
{
Type olType = Type.GetTypeFromProgID("Outlook.Application", false);
app = Activator.CreateInstance(olType) as Application;
ns = app.GetNamespace("MAPI");
ns.Logon(null, null, false, false);
app.NewMailEx += app_NewMailEx;
for (; ; )
{ Thread.Sleep(10000); }
}
static void app_NewMailEx(string EntryIDCollection)
{
Console.WriteLine("New mail event triggered, running on background worker...");
var bg = new BackgroundWorker();
bg.DoWork += bg_DoWork;
bg.RunWorkerAsync(EntryIDCollection);
Console.WriteLine("New mail event ended, returning");
}
static void bg_DoWork(object sender, DoWorkEventArgs e)
{
Thread.Sleep(5000);
Console.WriteLine("New mail thread started");
string EntryIDCollection = (string)e.Argument;
foreach (var id in EntryIDCollection.Split(','))
{
if (ns.GetItemFromID(id) is MailItem)
{
Console.WriteLine(id + " is a mail item");
}
}
Console.WriteLine("New mail thread Ended");
}
}
}
Thread.Sleep(5000);
見通しの間、幸せで敏感なままです。以下Console.WriteLine
が呼び出されるまでに、元のapp_NewMailEx
イベント ハンドラーはかなり前に返されています。
ただし、その行でブレークポイントを設定したり、アプリケーションをロックして集中的なタスクを実行したりすると、イベントが再起動されていなくても、その間 Outlook は応答しません。
メッセージが到着したときにイベント ハンドラーを削除し、完了したら再度追加するとbg_DoWork
、問題は軽減されますが、これは、メッセージがこの 2 回の間に到着すると、メッセージが失われることを意味します。
なぜこれが起こるのですか?また、この状況で Outlook が応答しなくなるのを防ぐにはどうすればよいですか?