【问题标题】:C# COM Add In failing while calling from threadC# COM Add In 在从线程调用时失败
【发布时间】:2012-06-27 13:00:19
【问题描述】:

我正在用 C# 为 Excel 编写 UDF 库。我将长期运行 UDF,所以我想让我的 UDF 异步,以便 Excel UI 在调用 UDF 时保持可用。以下是我的代码;但从衍生线程调用 Excel 时失败...

[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
[ComDefaultInterface(typeof(IRAPDataAddIn))]
public class RAPDataAddIn : IRAPDataAddIn
{

    public string GetPositionData(Excel.Range Portfolios, Excel.Range Security)
    {





        Excel.Application excelApp = (Excel.Application)Marshal.GetActiveObject("Excel.Application");

        Excel.Range target = (Excel.Range)excelApp.get_Caller(System.Type.Missing);


        Thread _workerThread = new Thread(new ParameterizedThreadStart(this.GetData));
        _workerThread.CurrentCulture = System.Globalization.CultureInfo.CurrentCulture;
        _workerThread.CurrentUICulture = System.Globalization.CultureInfo.CurrentUICulture;

        _workerThread.Start(target);

        return "Getting Data";
    }


    public void GetData(object Range)
    {
        Excel.Range target = Range as Excel.Range;

        Thread.Sleep(1000);

        object[,] returnData = new object[2,2];

        returnData[0, 0] = " FirstThread";       
        returnData[0, 1] = " SecondThread"; 
        returnData[1, 0] = " ThirdThread";              
        returnData[1, 1] = " FourthThread";  

        var Start = (Excel.Range)target.Worksheet.Cells[1,1];
        var End = (Excel.Range)target.Worksheet.Cells[2,2];

        Excel.Range r = (Excel.Range)target.Worksheet.Range[Start, End];

        try
        {
            r.Value2 = returnData; ***//It fails here***
        }
        catch (Exception ex)
        {

        }
    }

【问题讨论】:

  • “失败”不是合适的诊断。强迫我们猜测你知道的东西、异常消息和堆栈跟踪是没有意义的。

标签: c# excel com user-defined-functions


【解决方案1】:

(免责声明:我开发 Excel-DNA 库)

我建议您使用(免费)Excel-DNA 库来实现您的 Excel UDF。我最近添加了一些对异步函数的实验性支持,所以现在是尝试它的好时机。我将当前异步函数支持的初步概述放在这里:http://exceldna.codeplex.com/wikipage?title=Asynchronous%20Functions&referringTitle=Documentation。支持 Excel-DNA 的最佳地点是Excel-DNA Google group

您的方法存在一些潜在问题:

  • 您使用Marshal.GetActiveObject 检索的应用程序对象可能不是您正在运行的 Excel 实例。如果已启动多个 Excel 实例,则它将是最近启动的 Excel。

  • 您不能只将“Range”COM 对象传递给另一个线程 - 它是一个 STA 单元绑定对象,因此不能从不是主 Excel 线程的线程中使用,除非明确交叉-线程编组。

  • 如果 Excel 正忙,例如 Excel 正忙于计算,或者用户正在编辑单元格,甚至只是按下鼠标按钮,则从其他线程到 Excel 的任何 COM 调用都可能失败。因此,作为正常操作的一部分,每个 COM 调用都需要处理可能的异常。

有几种方法可以使用 Excel-DNA 实现这种工作,因此如果需要更具体的指导,您应该查看库并发布到 Google 小组。

【讨论】:

  • 嗨,Govert;在您推荐后,我开始使用 ExcelDna... 我将长期运行 UDF,它将从不同的服务器收集数据并将其返回给 Excel 客户端。因此,我可以通过维护 ExcelReference 将数据异步粘贴到所需位置(即从调用函数的单元格);但我也想在单元格中保留原始公式。我该怎么做?
  • 听起来您需要了解一下 Excel-DNA 中新的反应式扩展支持。这将允许您非常轻松地将数据异步推送到单元格中。在此处查看:exceldna.codeplex.com/… 并在此处向 Google 群组提问:groups.google.com/group/exceldna
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多