Autodesk Revit插件异步上报导致调用程序集变为mscorlib的问题求助
问题描述
在Autodesk Revit中开发自定义插件时,将同步使用上报功能改为异步实现后遇到程序集版本记录错误的问题:
- 原同步上报会导致UI卡顿1秒,异步改造后功能运行正常,但调用程序集变为
mscorlib,导致使用报告中记录的是微软该程序集的版本,而非插件自身版本。 - 尝试过
Assembly.GetCallingAssembly()、Assembly.GetExecutingAssembly()和Assembly.GetEntryAssembly()三种方法,均无法获取到调用上报方法的插件程序集。
代码示例:
Version assemblyVersion = Assembly.GetCallingAssembly().GetName().Version;
可行解决思路
同步提前获取版本再传入异步方法
在进入异步逻辑的同步上下文阶段,先获取插件的程序集版本,将其作为参数传入异步方法。此时Assembly.GetExecutingAssembly()可以正确指向插件程序集,避免异步线程上下文切换导致的偏差。
示例代码:// 同步上下文获取版本 Version pluginVersion = Assembly.GetExecutingAssembly().GetName().Version; // 传入异步上报方法 await Task.Run(() => ReportUsage(pluginVersion)); // 异步上报方法 private void ReportUsage(Version pluginVersion) { // 使用传入的pluginVersion完成上报逻辑 }初始化阶段缓存插件版本
利用Revit插件的入口方法(如IExternalApplication.OnStartup或IExternalCommand.Execute,均为同步执行)提前缓存插件程序集版本,后续异步上报时直接读取缓存值。
示例代码:// 插件类中定义静态缓存字段 private static Version _pluginVersionCache; // 插件入口方法中初始化缓存 public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { _pluginVersionCache = Assembly.GetExecutingAssembly().GetName().Version; // 其他业务逻辑 return Result.Succeeded; } // 异步上报时使用缓存 private async Task SubmitUsageReport() { if (_pluginVersionCache != null) { // 基于_cachedPluginVersion完成上报 } }通过堆栈跟踪定位插件程序集
遍历当前堆栈跟踪,筛选出属于插件程序集的调用帧,从中提取版本信息。该方式性能略低,需明确插件程序集的标识(如名称、公钥)。
示例代码:var stackTrace = new StackTrace(); Version pluginVersion = null; foreach (var frame in stackTrace.GetFrames()) { var method = frame.GetMethod(); var assembly = method.DeclaringType.Assembly; // 替换为你的插件程序集名称 if (assembly.GetName().Name.Equals("YourPluginAssemblyName", StringComparison.Ordinal)) { pluginVersion = assembly.GetName().Version; break; } }
更新
已通过同步获取插件版本并将其作为字符串参数传入异步方法的方式解决了该问题。
内容的提问来源于stack exchange,提问作者floretti
相关产品推荐
相关产品推荐

