【问题标题】:Improve performance by using Asynchronous web method call?通过使用异步 Web 方法调用来提高性能?
【发布时间】:2011-08-26 10:25:07
【问题描述】:

我现在正在做的项目的主要重点是创建一个 Excel 自动化函数 (CEF),它允许用户根据函数中提供的参数获取相关数据。 CEF 将在用户使用以下公式时填充单元格,“=CEF(id, [param1],[param2], ..."

public string CEF(string id, string param1 = "", string param2 = "", string param3 = "", string param4 = "") 
{ 
    return results; 
}

它的后面是一个 Web 方法 (getDataString()),它被 CEF 公开和调用,以便它可以通过 Web 服务从数据库中检索结果。

在最初的实现中,我使用了同步的方式来调用web方法,结果发现问题很大。 Excel 冻结,直到返回所有结果。

所以我决定在这里尝试使用 异步 方法 (the example I followed),但它实际上给了我一个新问题——CEF 总是返回 null。

void getDataStringCompleted(object sender, getDataStringCompletedEventArgs args)
{
    results = args.Result;
}

我猜我总是得到空值的原因可能是因为CEF 总是首先被击中,因此返回一个空字符串。目前我有点卡住了,不知道从这里去哪里。任何人都可以帮助或给我一些指示吗?非常感谢。

编辑:

在调试代码时,我发现挂钩事件的代码可能无法正常工作。

public string CEF(string id, string param1 = "", string param2 = "", string param3 = "", string param4 = "") 
{ 
    MyWebservice service = new MyWebservice();

    //Hookup async event handler
    service.getDataStringCompleted += new 
        getDataStringCompletedEventArgs(this.getDataStringCompleted); // <=problem 
    service.getDataStringAsync(id,param1, param2, param3, param4); // <=problem
    return results; 
}

不知道有没有什么方法可以先调用getDataStringCompleted,给变量results赋值,然后在方法CEF中返回。

【问题讨论】:

  • 如果您唯一更改的是使用异步函数而不是同步函数调用它,那么结果应该不会改变。你能把代码贴在你调用它的地方吗?
  • @Tridus 你能再看一下帖子(编辑部分)吗?谢谢。

标签: c# .net web-services excel asynchronous


【解决方案1】:

嗯,第一个问题是您在CEF 中返回results,而实际上没有。

public string CEF(string id, string param1 = "", string param2 = "", string param3 = "", string param4 = "") 
{ 
    MyWebservice service = new MyWebservice();

    //Hookup async event handler
    service.getDataStringCompleted += new 
        getDataStringCompletedEventArgs(this.getDataStringCompleted); 
    service.getDataStringAsync(id,param1, param2, param3, param4); 
    return results; // <- Isn't set yet!
}

在异步调用中,您无法从调用方法的位置返回结果。它是事件处理程序,只要它触发就会产生结果。在您的情况下,您在事件处理程序设置它之前返回resultsCEF 在这种情况下将无法返回值。您的事件处理程序必须获取该值并将其放入相应的单元格中。

有时在使用 OFFICE 时,要让异步工作正常工作要困难得多。可悲的是,这是其中之一。如果 Excel 需要 CEF 返回一个值,我不确定你将如何解决这个问题,因为你必须阻止一种或另一种方式,直到你从服务中取回一个(这是最简单的方法)只是同步调用它)。

【讨论】:

  • 感谢 Tridus 的回答。我目前正在 MSDN (msdn.microsoft.com/en-us/library/2e08f6yc.aspx) 上阅读这篇文章,似乎还有其他一些替代方案可以最好地解决我的问题。您如何看待这些提供的方法?
  • 我认为他们都有同样的问题。您可以做的是让 CEF 返回“等待”或其他内容以表明它正在处理。当事件处理程序返回一个值时,将其存储在某处并让 Excel 在工作表上重新计算。第二次让 CEF 检查它是否已经具有该值(它确实是因为您刚刚得到它),因此您可以立即返回正确的值。这会以你想要的方式结束,但它有点迂回。 .net 的所有异步方法都存在与您现在使用的相同的问题,因为问题在于 Excel。
  • 感谢 Tridus。我还发现了一些对异步 UDF 有更深入了解的其他文章。 (blogs.office.com/b/microsoft-excel/archive/2010/01/27/…)
  • 另外,我猜想存储从事件处理程序返回的值的挑战之一是将值放入适当的单元格中,这将是困难的。可能需要使用 VBA 什么的。
【解决方案2】:

就个人而言,当需要将数据直接流式传输到电子表格时,我非常喜欢 RTD 功能。在这种情况下,它可能会有点矫枉过正。 [关于 RTD 的好文章:http://support.microsoft.com/kb/285339]

当您说您的函数返回“null”时 - 您是在几秒钟或几分钟后刷新电子表格 [F9] 并且仍未提供值吗?

【讨论】:

    【解决方案3】:

    据我了解的问题,我想你会找到你需要的here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-16
      • 2018-01-20
      • 2019-08-06
      • 1970-01-01
      • 2018-11-17
      • 2016-06-08
      相关资源
      最近更新 更多