2011-08-31 149 views
1

我有一些C#代码写入进度消息到Visual Studio 2010 EnvDTE.OutputWindowPane。该代码是从Visual Studio菜单调用的(它位于VSPackage中)。刷新Visual Studio输出窗口

问题是,直到菜单选取所有处理完成后,输出窗口才会重新绘制,因此输出会一次显示,而不是每次添加时。我怀疑这与在主线程上执行的所有处理有关,因此Visual Studio UI无法重绘。

有没有办法在Visual Studio中“抽取消息”来更新UI - 比如Application.DoEvents()? VSPackage还在项目中插入了一些项目,这似乎是“即时”发生的 - 它只是输出窗口看起来滞后。

我通过各种DTE对象进行了搜索,但未找到任何此功能的候选对象。

+0

这听起来像是正确的解决方案是只是不做处理的UI线程。 – perelman

+0

是的,计划是尝试将处理移动到工作线程,但这需要大量的时间,并且我担心线程安全的某些VS接口是否有线程关联。在已知的安全点推送消息看起来风险较小。 – UweBaemayr

+0

我很困惑你的问题是什么。任何UI更改都应该发生在UI线程上。你可以通过记住'dispatcher = System.Windows.Threading.Dispatcher来确保。CurrentDispatcher'在UI线程的代码中,然后使用'dispatcher'从另一个线程执行任何UI更改(如果要保证邮件按照发送顺序显示,可能还需要一些额外的功能)。 – perelman

回答

1

对不起沉默 - 我只是想起了这个问题,并认为我会自己回答。

我能够很大程度上解决问题,方法是创建一个进度条窗口,当Visual Studio主线程关闭运行我的代码并且不更新UI时出现。进度条(IVsThreadedWaitDialog2)记录很差,但似乎在工作线程上运行,并在激活时将Visual Studio置于模态。这样至少可以让Visual Studio在处理过程中看起来像挂起一样。

进度条窗口与Visual Studio加载大型解决方案时显示的窗口相同,并且具有“取消”按钮的选项。

不幸的是,进度条对话框有几个bug(向Microsoft报告),其中最重要的是它经常出现在Visual Studio窗口的后面 - 真的很烦人。这是一种表现障碍,所以无论何时更新进度栏,我都会使用代码here的变体,通过其标题找到进度窗口,并将其放到Visual Studio窗口堆栈的顶部。

将处理移动到工作线程并不能很好地工作,因为它会执行在Visual Studio编辑器中操作文本的共享代码,并且这些操作的结果是不稳定的(有时会起作用,有时会出现一个不可思议的COM错误被返回,这似乎是时间依赖性的)。

我也终于在Visual Studio中找到了一个消息泵 - 该shell包含一个名为的类CommonMessagePump。再一次,它的记录很差,根据可用的信息,我永远无法完成正确的工作。无论如何,进度对话已经解决了我的问题。

1

在我的情况下,我能够在写入输出窗口后立即调用System.Windows.Forms.Application.DoEvents()并解决了问题。

相关问题