2010-10-25 2 views
1

Я пишу небольшое тестовое приложение для тестирования интерфейса связи. Интерфейс связи написан на C++ (DLL) и тестовом приложении с использованием C#. Интерфейс связи в свою очередь говорит о аппаратном стеке низкого уровня, который использует сообщения Windows для передачи и приема данных. Чтобы достичь этого, DLL-интерфейс коммутации создает невидимое дочернее окно, чей родитель является окном приложения C#. Последовательность, чтобы поговорить с оборудованием, следующая:Вызов функции блокировки

  1. Инициализировать библиотеку связи. Этот шаг ожидает, что дескриптор главного окна и экземпляр приложения передается в стек низкого уровня для обмена сообщениями Windows.

  2. Connect, используя адрес устройства

  3. Чтение/запись

  4. Закрыть

  5. деинициализации библиотеке связи.

Теперь, на втором этапе, DLL создает невидимое окно для связи с аппаратным стеклом низкого уровня. Поскольку второй шаг является блокирующим вызовом, я хочу, чтобы мой пользовательский интерфейс был отзывчивым в течение этого времени в случае, если потребуется много времени для подключения. Поэтому я пытаюсь подключиться асинхронно с помощью потока или вызова BeginInvoke. Но я заметил, что после установления соединения окно приложения зависает, пока существует дочернее окно. Окно дочернего окна блокирует все входящие сообщения в главном окне. Кажется, это связано с тем, что дочернее окно создается в другом потоке.

Но я не хочу, чтобы соединение было в основном потоке, поскольку он висит в пользовательском интерфейсе.

Я бы приветствовал любые идеи о том, как избежать этой проблемы? Заранее спасибо.

-Harish

+0

Просто любопытно, почему 2 является блокирующим звонком? Ваш код продолжает опрос, чтобы узнать, подключено ли устройство? В качестве решения, почему вы создаете дочернее окно - создайте окно только для сообщений верхнего уровня (http://msdn.microsoft.com/en-us/library/ms632599(VS.85).aspx#message_only). – VinayC

+0

Hi Vinay, я не создаю дочернее окно. Я использую только DLL, разработчик которой сделал это именно так. Я полагаю, что внутри DLL имеет тайм-аут, чтобы узнать, было ли соединение выполнено. Это очень большой тайм-аут и, таким образом, оказывает блокирующее влияние на мое приложение. Часть проблемы также связана с провайдером стека связи – HIyer

ответ

0

Все коммуникации с оконной ручки должно быть сделано на нить эта ручка была создана на. Это, вероятно, означает, что все вызовы DLL должны выполняться во вторичном потоке.

Вы можете попробовать следующее:

  • Перед инициализации DLL, запустить фоновый поток;
  • В этой теме создайте окно WinForms, которое вы не видите. Вы можете сделать это так:

-

public static Form BackgroundForm; 

[STAThread] 
static void Main() 
{ 
    Application.EnableVisualStyles(); 
    Application.SetCompatibleTextRenderingDefault(false); 

    new Thread(new ThreadStart(Secondary)).Start(); 

    Application.Run(new MainForm()); 
} 

static void Secondary() 
{ 
    BackgroundForm = new Form(); 

    // Calling Handle creates the system HWND. You do not have to call Show 
    // or something similar on this Form to make the handle available or use 
    // Invoke or BeginInvoke. 

    var handle = BackgroundForm.Handle; 

    // Initialize the DLL here with the handle. 

    Application.Run(); 

    // Unintialize the DLL. 
} 
  • Затем инициализировать библиотеку DLL с ручкой вы получили от фона формы;
  • Если вам нужно сделать звонки в DLL, сделайте это, используя Invoke и BeginInvoke в этой фоновой форме;
  • Как только пришло время закрыть приложение, сделайте Application.ExitThread() через Invoke или BeginInvoke.

Проблема, с которой вы сталкиваетесь с основной формой, является, вероятно, потому, что дочернее окно, созданное в DLL, имеет дескриптор основной формы, поскольку это родительское окно, но это только предположение. Вероятно, это также можно решить с помощью этой системы.

+0

Спасибо, Питер, я проверю это. Кажется, это хорошая вещь, чтобы попробовать. Еще раз спасибо. – HIyer

+0

Добро пожаловать. –