Почему мой вызов DDE из Excel зависает после получения уровня рендеринга приложения .Net с использованием пула потоков? - PullRequest
5 голосов
/ 03 июня 2011

Я обнаружил очень странную проблему, когда, если я получу уровень рендеринга приложения .Net с помощью ThreadPool, он повесит очень простой вызов DDE из Excel. Эта проблема наблюдалась при запуске сложного приложения WPF одновременно с вызовом DDE из Excel. Мне удалось воспроизвести проблему в нескольких строках кода, которые можно найти ниже.

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();
    }
}

Макрос 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 возвращается к жизни. Получение уровня рендеринга из основного потока не вызывает проблемы. Я также заметил, что если отладчик приостановлен, макрос зависнет, даже если вызов для получения уровня рендеринга не был сделан.

Проблема реплицирована с использованием Windows Xp с Excel 2003, .Net3.5 & .Net4 и Windows 7 с Excel 2010, .Net3.5 & .Net4.

Есть идеи, почему это происходит? Это ошибка в PresentationCore.dll?

Спасибо за вашу помощь

[Update]

Изменение уровня рендеринга машины, кажется, освобождает этот «замок» (потом мне пришлось немного передвинуть окна). Я изменил уровень рендеринга, запустив NetMeeting, но это можно сделать, заставив вашу графическую карту использовать программный рендеринг в свойствах экрана.

1 Ответ

3 голосов
/ 09 июня 2011

Может быть, это поможет:

Если другая программа, работающая на компьютере под управлением Windows 2000 или Windows XP, неправильно обрабатывает цикл сообщений Windows, программа, использующая DDEперестает отвечать.

Вы можете найти его здесь .

Это происходит только в 32-битной Windows, и затрагиваются только клиенты DDE.Чтобы установить соединение, приложение передает сообщение всем окнам верхнего уровня.Если окно не в том же потоке, сообщение фактически отправляется в очередь получателей, и вызывающая сторона блокируется.Если у получателя нет очереди сообщений, вызывающий поток постоянно блокируется.Microsoft признала, что это ошибка.

Более подробная информация содержится в статье базы знаний Q136218 BUG: DdeConnect никогда не возвращается.

...