この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で非同期イベントをトリガーするための他の提案はありますか?