1

このC#コードは、.NET4.5ComVisibleアセンブリに含まれています。

C#コード

[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[Guid("22341223-9264-12AB-C1B4-B4F112014C31")]
public interface IComWithTask
{
    void LongExecutionMethod(double x);
    void LongExecutionMethodAsync(double x);
}

[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
[Guid("23844123-9274-12CB-C1F4-B4F1521E4F33")]
public interface IComWithTaskEvents
{
    void OnLongExecutionMethodComplete(double x);
}

[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces(typeof(IComWithTaskEvents))]
[Guid("E4F27AA4-1932-2196-1234-121CF2722C42")]
[ProgId("ComWithTask")]
public class ComWithTask : IComWithTask
{
    [ComVisible(false)]
    public delegate void LongExecutionMethodComplete(double x);
    public event LongExecutionMethodComplete OnLongExecutionMethodComplete;

    public void LongExecutionMethod(double x)
    {
        if (OnLongExecutionMethodComplete != null)
        {
            OnLongExecutionMethodComplete(x * x);
        }
    }

    public void LongExecutionMethodAsync(double x)
    {
        Task.Factory.StartNew(state =>
        {
            var onLongExecutionMethodComplete = OnLongExecutionMethodComplete;
            if (onLongExecutionMethodComplete != null)
            {
                onLongExecutionMethodComplete(x * x);
            }
        }, null);
    }
}

Excel 2010 32ビットVBAから、次の動作が発生します。

VBAコード

Private WithEvents oComWithTask As ComWithTask

Public Sub Class_Initialize()
    Set oComWithTask = New ComWithTask
End Sub

Public Sub LongExecutionMethod()
    ' Works as expected
    Call oComWithTask.LongExecutionMethod(2)
End Sub

Public Sub LongExecutionMethodAsync()
    ' Does NOT work!
    Call oComWithTask.LongExecutionMethodAsync(3)
End Sub

Private Sub oComWithTask_OnLongExecutionMethodComplete(ByVal x As Double)
    MsgBox x
End Sub

を呼び出すときに.NET内でスレッドを回転させていることLongExecutionMethodAsync、およびオフィスアプリケーションがシングルスレッドであることを認識しています。

マルチスレッド方式で.NETからCOMコンポーネントを呼び出すことに関する優れた文献を見つけましたが、逆に、つまりVBAがCOMメソッドでラップされたマルチスレッド.NETを呼び出すリソースを見つけることができませんでした。

マルチスレッドを使用する方法についてLongExecutionMethodAsync何か考えがありますか?このテーマに関連するリソースを教えていただけますか?また、VBAで非同期イベントをトリガーするための他の提案はありますか?

4

1 に答える 1

1

上記のコードは期待どおりに機能しています。問題は、イベントが発生する前に死んでいたVBA内のオブジェクトの寿命でした。

于 2012-10-24T10:14:06.010 に答える