尝试处理在Windows 8或Windows 10上的Office 2016 64位中的多线程C#dll引发的事件时出错。它适用于32位和64位版本的Office 2013。它适用于Server 2008和Server 2012 R2上的Office 16 64位。错误是运行时错误'-2146232829(80131603)'对象与目标类型不匹配。
堆栈跟踪是:
at System.RuntimeType.InvokeDispMethod(String name,BindingFlags invokeAttr,Object target,Object [] args,Boolean [] byrefModifiers,Int32 culture,String [] namedParameters)
at System.RuntimeType.InvokeMember(String name,BindingFlags bindingFlags,Binder binder,Object target,Object [] providedArgs,ParameterModifier [] modifiers,CultureInfo culture,String [] namedParams)
at System.RuntimeType.ForwardCallToInvokeMember(String memberName,BindingFlags flags,Object target,Int32 [] aWrapperTypes,MessageData& msgData)
at COMTest.ICounterEvents.CounterProgressed(Object sender,CounterProgressedEventArgs e) 在COMTest.Counter.IncrementCounter()
c#代码是:
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace COMTest
{
[ComVisible(true), InterfaceType(ComInterfaceType.InterfaceIsDual), Guid("1912B8CF-0B0A-4F9D-A76D-5C10D6B85548")]
public interface ICounter
{
void Progress();
int Count { get; }
}
[ComVisible(true), InterfaceType(ComInterfaceType.InterfaceIsDual), Guid("5150CD23-DF7A-4FBE-838A-7AFEA84A0CFC")]
public interface ICounterProgressedEventArgs
{
int Progress { get; }
}
[ComVisible(true), ClassInterface(ClassInterfaceType.None)]
public class CounterProgressedEventArgs : EventArgs, ICounterProgressedEventArgs
{
public int Progress { get; internal set; }
}
[ComVisible(true), InterfaceType(ComInterfaceType.InterfaceIsIDispatch), Guid("1698856D-AFDA-4C94-B6B4-5EA94958B40D")]
public interface ICounterEvents
{
[DispId(1)]
void CounterProgressed(object sender, CounterProgressedEventArgs e);
}
[ComSourceInterfaces(typeof(ICounterEvents))]
[ComVisible(true), ClassInterface(ClassInterfaceType.None)]
[Serializable]
public sealed class Counter : ICounter
{
public event CounterProgressedEventHandler CounterProgressed;
public delegate void CounterProgressedEventHandler(object sender, CounterProgressedEventArgs e);
public int Count { get; private set; }
public void Progress()
{
if (CounterProgressed != null)
{
RunTasks(5);
}
}
private void RunTasks(int threads)
{
var tasks = new Dictionary<int, Action>();
var asyncResults = new IAsyncResult[threads];
for (int i = 0; i < threads; i++)
{
tasks.Add(i, IncrementCounter);
}
for (int i = 0; i < threads; i++)
{
var task = tasks[i];
asyncResults[i] = task.BeginInvoke(null, null);
}
for (int i = 0; i < threads; i++)
{
var task = tasks[i];
task.EndInvoke(asyncResults[i]);
}
}
private void IncrementCounter()
{
if (CounterProgressed != null)
{
Count++;
CounterProgressed(this, new CounterProgressedEventArgs { Progress = Count });
}
}
}
}
我运行tlbexp来生成类型库。
我运行了regasm / codebase来注册dll。
我在Excel中创建了Class1
,如下所示:
Public WithEvents comCounter As Counter
Public Sum As Long
Public Sub Test()
Set comCounter = New Counter
comCounter.progress
End Sub
Private Sub comCounter_CounterProgressed(ByVal sender As Variant, ByVal e As COMTest.ICounterProgressedEventArgs)
Sum = Sum + e.progress
Range("A1").Value = Sum
End Sub
我使用以下宏调用Class1
:
Public Sub Run()
Dim c As Class1
Set c = New Class1
c.Test
End Sub
执行时,宏应在单元格A1中显示15,但抛出“对象与目标类型不匹配”异常。