C#VSTO从其他加载项调用异步方法,并等待响应

时间:2017-10-27 11:22:51

标签: c# asynchronous outlook vsto outlook-addin

我有一个正在运行的Outlook加载项,它有一个公开的异步函数,它返回一个

System.Threading.Tasks.Task<String> object.

当我从另一个应用程序调用此方法时,我得到以下异常:

System.__ComObject' does not contain a definition for 'GetAwaiter'

我的Outlook异步功能作业是:

  1. 发送和接收新电子邮件
  2. 如果有新电子邮件进入,请通过ItemAdd事件处理
  3. 如果处理完成,则创建一份报告
  4. 将此报告返回我的其他应用程序
  5. 我如何从主机应用程序调用异步方法:

    public static async void GetOutlookReport() 
    {
        object addInName = "myOutlookAddIn";
        var outlookApplication = (Microsoft.Office.Interop.Outlook.Application)Marshal.GetActiveObject("Outlook.Application");
        Office.COMAddIn addIn = outlookApplication.COMAddIns.Item(ref addInName);
        if (addIn != null)
        {
            String Report = await addIn.Object.myAsyncOutlookFunction("parameter1"); //failes here
            //do whatever with report...
        }
    }
    

    如何在Outlook插件中声明方法:

    -My Ribbon.cs类文件包含以下内容:

    [ComVisible(true)]
    public interface IAddInUtilities
    {
        System.Threading.Tasks.Task<String> myAsyncOutlookFunction(String Param1);
    }
    
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    public class AddInUtilities : StandardOleMarshalObject,
    IAddInUtilities
    {
        public async System.Threading.Tasks.Task<String> myAsyncOutlookFunction(String Param1)
        {
            String x = await myAsyncOutlookFunctionDefined(Param1);
            return x;
        }
    }
    

    - myAsyncOutlookFunctionDefined的实现:

    public static async Task<String> myAsyncOutlookFunctionDefined(String Param1)
    {
        try
        {
            //try to get all new emails in
            await CallSendAndReceive(); //function that simply calls NameSpace.SendAndReceive();
    
            //after SendAndReceive finished, the ItemAdd events should run (code not implemented yet)
            //after ItemAdd events have finished we create the report
    
            String Report = CreateReport(); //this function is irrelevant right now
            return Report;
        }
        catch(Exception ex)
        {
            return "";
        }
    }
    

    甚至可以从我的主机应用程序等待

    • Outlook以SendAndReceive
    • 结束
    • 运行收件箱文件夹中的所有ItemAdd事件
    • 自己做处理
    • 通过字符串形式将报告发送回主机应用程序?

    想法是,运行该函数最多30秒,如果它没有完成获取电子邮件,并处理它们以创建报告,那么只返回一个空字符串。

    如果我无法通过从其他应用程序(主机)调用异步函数的响应,我无法继续进行此开发。

    注意:

    为了好玩,我在Outlook加载项中添加了一个按钮,模拟了相同的操作。当我单击按钮时,我可以调用相同的myAsyncOutlookFunction,但是,我不是通过Office.COMAddIn对象调用它,而是直接调用它。它运行顺畅,这意味着System.Threading.Tasks.Task对象具有正确的数据。

    这种证明,通过暴露的类调用它是问题的根源......

1 个答案:

答案 0 :(得分:0)

缺少GetAwaiter()调用似乎表明运行调用代码的框架版本不支持async / await。测试使用纯TPL调用该方法(不使用async / await关键字)。