Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

WPF + QueueUserWorkItem + RegisterDeviceNotification

2 réponses
Avatar
Loïc Berthollet
Bonjour.

J'ai une appli WPF qui dialogue avec périphérique USB (classe HID).
L'appli WPF charge une fenêtre WinForms qui s'enregistre auprès du système
via l'API "RegisterDeviceNotification" pour être notifiée de l'arrivée ou du
départ du périphérique.

Tout fonctionne bien quand la winform est crée sur le même thread que
l'application.

Mais, si la fenêtre winform est crée via ThreadPool.QueueUserWorkItem sur un
thread du pool, elle n'est pas notifié par le système lorsque le
périphérique est branché !

Une idée ?

PS: Les thread du pool sont de type MTA, WPF est de type STA; y aurait-il un
rapport ?

2 réponses

Avatar
Gilles Kohl [MVP]
On Mon, 2 Jun 2008 01:16:29 +0200, Loïc Berthollet
wrote:

Bonjour.

J'ai une appli WPF qui dialogue avec périphérique USB (classe HID).
L'appli WPF charge une fenêtre WinForms qui s'enregistre auprès du système
via l'API "RegisterDeviceNotification" pour être notifiée de l'arrivée ou du
départ du périphérique.

Tout fonctionne bien quand la winform est crée sur le même thread que
l'application.

Mais, si la fenêtre winform est crée via ThreadPool.QueueUserWorkItem sur un
thread du pool, elle n'est pas notifié par le système lorsque le
périphérique est branché !

Une idée ?

PS: Les thread du pool sont de type MTA, WPF est de type STA; y aurait-il un
rapport ?



Ca ce pourrait bien - une application WinForm générée p.ex. par Visual
Studio a toujours cette forme:

[STAThread]
static void Main()
// etc.

Donc les fenètres crées en aval sont seront sur le STA, que WinForms
nécessite pour un fonctionnement correct selon MSDN.

Amicalement,
Gilles.

Regards,
Gilles [MVP].

(Please reply to the group, not via email.
Find my MVP profile with past articles / downloads here:
http://www.gilleskohl.de/mvpprofile.htm)
Avatar
Loïc Berthollet
Merci de ta réponse Gilles.

Entre temps, j'ai remarqué une autre anomalie étrange.
Pour résumé :
- l'appli WPF se lance.
- Elle crée, sur un autre thread que appellerai TX, une série d'objets. Un
de ces objets crée et affiche la winform; un autre de ces objet crée un
FileStream et initie une lecture asynchrone dessus via BeginRead( ...)

- quand TX est un thread de travail type STA (Background= false,
PoolThreadúlse) : le BeginRead renvoie l'erreur OperationCanceled.
- quand TX est un thread de travail type MTA (Background= false,
PoolThreadúlse) : même erreur.
=> Le FileStream étant crée et géré sur ce thread TX, il n'y a pas
d'erreur de cross-threading. Certes, ce n'est pas le thread principal. Et
alors ?
=> Cerise sur le gateau: le BeginRead qui plante sous XP fonctionne sous
Vista; la winForm, elle, n'est jamais notifié, même sous Vista...

- quand TX est un thread du pool (type MTA, Background=true,
PoolThread=true) : le BeginRead asynchrone fonctionne, la winform crash à la
fermeture (mais c'est normal: son Dispose n'est pas appelé sur le bon thread
pour l'instant), mais surtout la winForm ne reçoit pas les notifications
système d'insertion et de suppression de périphérique; pourtant le système
accepte d'enregistrer la winForm via son handle, puis accepte à la fermeture
de la désenregistrer: je me demande où parte les notifications !

PS: quand je n'utilise pas un thread de travail TX et que je reste sur le
thread principal (type STA, Background= false, PoolThreadúlse), tout
fonctionne !

une autre idée ?

--------------------------------------------------


"Gilles Kohl [MVP]" <no_email_available@> a écrit dans le message de groupe
de discussion :
On Mon, 2 Jun 2008 01:16:29 +0200, Loïc Berthollet
wrote:

Bonjour.

J'ai une appli WPF qui dialogue avec périphérique USB (classe HID).
L'appli WPF charge une fenêtre WinForms qui s'enregistre auprès du système
via l'API "RegisterDeviceNotification" pour être notifiée de l'arrivée ou
du
départ du périphérique.

Tout fonctionne bien quand la winform est crée sur le même thread que
l'application.

Mais, si la fenêtre winform est crée via ThreadPool.QueueUserWorkItem sur
un
thread du pool, elle n'est pas notifié par le système lorsque le
périphérique est branché !

Une idée ?

PS: Les thread du pool sont de type MTA, WPF est de type STA; y aurait-il
un
rapport ?



Ca ce pourrait bien - une application WinForm générée p.ex. par Visual
Studio a toujours cette forme:

[STAThread]
static void Main()
// etc.

Donc les fenètres crées en aval sont seront sur le STA, que WinForms
nécessite pour un fonctionnement correct selon MSDN.

Amicalement,
Gilles.

Regards,
Gilles [MVP].

(Please reply to the group, not via email.
Find my MVP profile with past articles / downloads here:
http://www.gilleskohl.de/mvpprofile.htm)