为什么在我使用线程池获得 .Net 应用程序的渲染层后,来自 Excel 的 DDE 调用会挂起?

发布于 2024-11-13 09:35:26 字数 1710 浏览 2 评论 0原文

我发现了一个非常奇怪的问题,如果我使用 ThreadPool 获取 .Net 应用程序的渲染层,它将挂起来自 Excel 的非常简单的 DDE 调用。当从 Excel 调用 DDE 的同时运行复杂的 WPF 应用程序时,会出现此问题。我已经设法用几行代码重现了这个问题,如下所示。

C# .Net 应用程序

//Need to reference PresentationCore.dll
class Program
{
    private static int _renderTier;
    static void Main(string[] args)
    {
        ThreadPool.QueueUserWorkItem(x =>
                                         {
                                             _renderTier = RenderCapability.Tier;
                                             Console.WriteLine(_renderTier);
                                         });
        Console.ReadLine();
    }
}

Excel DDE 宏。

Sub Using_DDE1()

  ' Dimension the variables.
  Dim Chan As Integer
  Dim RequestItems As Variant

  ' Start a channel to Word using the System topic.
  Chan = DDEInitiate("WinWord", "System")

  ' Requesting information from Word using the Formats item
  ' this will return a one dimensional array.
  RequestItems = DDERequest(Chan, "Formats")

  ' Uses a FOR loop to cycle through the array and display in a message box.
  For i = LBound(RequestItems) To 3

      MsgBox RequestItems(i)

  Next i

  ' Terminate the DDE channel.
  DDETerminate Chan

  End Sub 

单独运行该宏时,会弹出 3 个消息框。如果我尝试在 C# 应用程序运行时运行宏,它将挂起对 DDEInitiate 的调用。一旦 C# 应用程序关闭,Excel 就会恢复活力。从主线程获取渲染层不会导致问题。我还注意到,如果调试器暂停,即使尚未调用获取渲染层,宏也会挂起。

使用带有 Excel 2003、.Net3.5 和 .Net3.5 的 Windows Xp 复制问题.Net4 和 Windows 7 以及 Excel 2010、.Net3.5 和.Net4。

知道为什么会发生这种情况吗?这是PresentationCore.dll 的错误吗?

感谢您的帮助

[更新]

更改机器的渲染层似乎可以释放此“锁定”(之后我不得不稍微移动窗口)。我通过启动 NetMeeting 来更改渲染层,但这可以通过强制显卡在显示属性中使用软件渲染来完成。

I have found a very strange issue where if I get the Rendering Tier of a .Net App using the ThreadPool it will hang a very simple DDE call from Excel. The issue was seen when running a complex WPF app at the same time as the DDE call from Excel. I have managed to reproduce the issue in a few line of code which can be found below.

C# .Net App

//Need to reference PresentationCore.dll
class Program
{
    private static int _renderTier;
    static void Main(string[] args)
    {
        ThreadPool.QueueUserWorkItem(x =>
                                         {
                                             _renderTier = RenderCapability.Tier;
                                             Console.WriteLine(_renderTier);
                                         });
        Console.ReadLine();
    }
}

The Excel DDE Macro.

Sub Using_DDE1()

  ' Dimension the variables.
  Dim Chan As Integer
  Dim RequestItems As Variant

  ' Start a channel to Word using the System topic.
  Chan = DDEInitiate("WinWord", "System")

  ' Requesting information from Word using the Formats item
  ' this will return a one dimensional array.
  RequestItems = DDERequest(Chan, "Formats")

  ' Uses a FOR loop to cycle through the array and display in a message box.
  For i = LBound(RequestItems) To 3

      MsgBox RequestItems(i)

  Next i

  ' Terminate the DDE channel.
  DDETerminate Chan

  End Sub 

Running the macro will bring up 3 message boxes when running on its own. If I try running the macro while the c# app is running it will hang on the call to DDEInitiate. As soon as the c# app is closed excel comes back to life. Getting the Rendering Tier from the Main thread does not cause the issue. I also noticed that if the debugger is paused the macro will hang even if the call to get the rendering tier hasn't been made.

Issue replicated using Windows Xp with Excel 2003, .Net3.5 & .Net4 and Windows 7 with Excel 2010, .Net3.5 & .Net4.

Any idea why this is happening? Is this a bug with the PresentationCore.dll?

Thanks for your help

[Update]

Changing the Rendering Tier of the Machine seems to release this 'lock' (I had to move the windows around a bit afterwards). I was changing the rendering Tier by starting NetMeeting but it can be done by forcing your Graphics Card to use software rendering in Display Properties.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

白昼 2024-11-20 09:35:26

也许这有帮助:

如果在基于 Windows 2000 或基于 Windows XP 的计算机上运行的另一个程序无法正确处理 Windows 消息循环,则使用 DDE 的程序将停止响应。

您可以在此处找到它。

这只发生在 32 位 Windows 中,并且只有 DDE 客户端受到影响。为了建立连接,应用程序向所有顶级窗口广播消息。如果窗口不在同一线程上,则消息实际上会发布到接收者队列,并且调用者会被阻止。如果接收者没有消息队列,则调用线程将被永久阻塞。 Microsoft 已承认这是一个错误。

更多详细信息请参阅知识库文章 Q136218 BUG:DdeConnect永不回归。

Maybe this helps:

If another program that is running on the Windows 2000-based or on the Windows XP-based computer does not correctly process an Windows message loop, the program that uses DDE stops responding.

You can find it here.

This only happens in 32-bit Windows, and only DDE clients are affected. To make a connection, an application broadcasts a message to all top level windows. If the window is not on the same thread, the message is actually posted to the recipients queue and the caller is blocked. If the recipient has no message queue the calling thread is permanently blocked. Microsoft has acknowledged that this is a bug.

Further details are in the Knowledgebase article Q136218 BUG: DdeConnect Never Returns.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文