首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Visual Studio2019中异步加载ModelingPackage (DSL-Tools)?

如何在Visual Studio2019中异步加载ModelingPackage (DSL-Tools)?
EN

Stack Overflow用户
提问于 2019-08-22 19:18:57
回答 1查看 113关注 0票数 1

我有一个DSL-tools项目,其中我使用[ProvideAutoLoad],因为它向Visual Studio添加了一组菜单命令,允许用户转换代码(我们有很多文本模板),以及其他一些事情。

由于VS2019确实会自动加载,所以即使打开了允许自动加载的选项,我也会收到令人讨厌的警告。

显然,微软没有计划提供ModelingPackage的异步版本(事实上,我开始质疑他们是不是在一起停止使用DSL工具)。

有没有人找到了解决这个问题的办法?

我尝试使用另一个包--构建为AsyncPackage --这样就可以在InitializeAsync()上加载我的DSL-tools包,但是使用IVsShell服务时,我遇到了各种各样的异常。

代码语言:javascript
复制
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<VSShell.ServiceProgressData> progress)
{
    // Default behavior

    await base.InitializeAsync(cancellationToken, progress).ConfigureAwait(false);

    // Load the service designer package

    this.EnsureDesignerPackage();

    // Switche to the UI thread

    await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

    // Menu commands

    this.InitializeMenuCommands();
}

private void EnsureDesignerPackage()
{
    // Package already loaded?

    if (!this.IsDesignerPackageLoaded())
    {
        this.LoadDesignerPackage();
    }
}

private bool IsDesignerPackageLoaded()
{
    // Package identifier

    Guid packageId = new Guid(GlobalConstants.ServiceDesignerPackageId);

    // Is loaded?

    IVsShell service = this.VsShellService;

    int hr = this.VsShellService.IsPackageLoaded(ref packageId, out IVsPackage package);
    if (ErrorHandler.Succeeded(hr) && package != null)
    {
        return true;
    }

    // Default result

    return false;
}

private void LoadDesignerPackage()
{
    // Package identifier

    Guid packageId = new Guid(GlobalConstants.ServiceDesignerPackageId);

    // Not loaded?

    int hr = this.VsShellService.IsPackageLoaded(ref packageId, out IVsPackage package);
    if (hr != VSConstants.S_OK || package == null)
    {
        // Load

        hr = this.VsShellService.LoadPackage(ref packageId, out package);
        if (ErrorHandler.Failed(hr))
        {
            string message = "Service designer loading failed: {0}.".Format().With(hr);
            this.ShowException(message);
        }
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-08-24 11:11:45

今天早些时候,我碰巧带一位客户经历了同样的情况。不幸的是,我最后一次问到,目前还没有计划更新底层的领域特定语言框架来利用AsyncPackage或类似的东西。我看到你已经在dev community site中记录了一条建议,于是我就在上面投了票并添加了我自己的$.02。我鼓励任何点击这个链接的人投票支持上面链接的建议。

要向DSL Package对象添加对异步加载的支持,您需要添加对Microsoft.VisualStudio.Shell.Interop.14.0.DesignTime.dll程序集的引用,然后编辑Package.tt文件,以添加AllowsBackgroundLoading设置为true的VSShell.PackageRegistration属性,并在同一个类上实现IAsyncLoadablePackageInitialize接口。例如:

代码语言:javascript
复制
namespace <#= CodeGenerationUtilities.GetPackageNamespace(this.Dsl) #>
{
    /// <summary>
    /// Double-derived class to allow easier code customization.
    /// </summary>
    [VSShell::ProvideMenuResource("1000.ctmenu", 1)]
    [VSShell::ProvideToolboxItems(1)]
    [VSShell::PackageRegistration(AllowsBackgroundLoading = true)]
    [global::Microsoft.VisualStudio.TextTemplating.VSHost.ProvideDirectiveProcessor(typeof(global::<#= this.Dsl.Namespace #>.<#= directiveName #>DirectiveProcessor), global::<#= this.Dsl.Namespace #>.<#= directiveName #>DirectiveProcessor.<#= directiveName #>DirectiveProcessorName, "A directive processor that provides access to <#= directiveName #> files")]
    [global::System.Runtime.InteropServices.Guid(Constants.<#= dslName #>PackageId)]
    internal sealed partial class <#= dslName #>Package : <#= dslName #>PackageBase, VSShellInterop.IAsyncLoadablePackageInitialize
    {
        public VSShellInterop.IVsTask Initialize(VSShellInterop.IAsyncServiceProvider pServiceProvider, VSShellInterop.IProfferAsyncService pProfferService, VSShellInterop.IAsyncProgressCallback pProgressCallback)
        {
            // do async initialization here
            return null;
        }
    }
}

由衷地,

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57608183

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档