Async + STA Thread State

Résolu
MiharbiDoNo Messages postés 150 Date d'inscription dimanche 17 mai 2009 Statut Membre Dernière intervention 25 mai 2012 - 18 juil. 2010 à 02:48
MiharbiDoNo Messages postés 150 Date d'inscription dimanche 17 mai 2009 Statut Membre Dernière intervention 25 mai 2012 - 19 juil. 2010 à 02:28
Bonjour,
pendant que j'utilise un tcpclient, avec les methodes async BeginRead, BeginWrite, je veux acceder au Clipboard, ce qui est impossible, car l'access au Clipboard demande que the thread wui va faire l'appel doit avoir STA Comme apartment Attitude. alors comment modifé l'attitude du thread qui va terminer l'operation async, au bien comme pouvoir acceder au Clipboard, sans cette attitude.
Merci.

10 réponses

MiharbiDoNo Messages postés 150 Date d'inscription dimanche 17 mai 2009 Statut Membre Dernière intervention 25 mai 2012
18 juil. 2010 à 16:58
Bonjour,
j'ai trouver une petite solution temporaire, c'est d'utilisé les api OpenClipboard, GetClipboardData et CloseClipboard. dommage que je peux pas utilisé la class Clipboard Du .net, mais bon on cherche encore de bonne solution.
merci.
3
foliv57 Messages postés 420 Date d'inscription vendredi 17 novembre 2006 Statut Membre Dernière intervention 15 juillet 2014 9
19 juil. 2010 à 00:02
Je viens de faire un essai avec d'autres delegate et c'est toujours le cas. Le thread de callback est toujours MTA. Je n'avais jamais fait attention ce point.

Dans ce cas je ne vois pas d'autre solution que de faire :
Private Sub EndReading(ByVal ar As IAsyncResult)
        Dim monParametreAStocker As Object
        Dim th As New Thread(AddressOf AccessClipBoard)
        th.SetApartmentState(ApartmentState.STA)
        th.Start(monParametreAStocker)
        th.Join()
End Sub

Private Sub AccessClipBoard(ByVal obj As Object)
        Clipboard.SetDataObject(obj)
End Sub
3
MiharbiDoNo Messages postés 150 Date d'inscription dimanche 17 mai 2009 Statut Membre Dernière intervention 25 mai 2012
19 juil. 2010 à 02:28
oui ça semble d'etre la seule methode, pour avoir un thread STA. ou bien faut utiliser les API du Clipboard. merci pour votre repense.
3
foliv57 Messages postés 420 Date d'inscription vendredi 17 novembre 2006 Statut Membre Dernière intervention 15 juillet 2014 9
18 juil. 2010 à 10:36
Bonjour,

Pour modifier l'apartment state d'un thread, il y a deux possibilités :

Pour le thread principal, on peut utiliser un attribut
<MTAThread> _
Shared Sub Main()
End Sub

ou
<STAThread> _
Shared Sub Main()
End Sub


Pour un thread créé par code
Dim newThread As Thread = New Thread(AddressOf ThreadMethod)
newThread.SetApartmentState(ApartmentState.MTA)

ou
Dim newThread As Thread = New Thread(AddressOf ThreadMethod)
newThread.SetApartmentState(ApartmentState.STA)
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
MiharbiDoNo Messages postés 150 Date d'inscription dimanche 17 mai 2009 Statut Membre Dernière intervention 25 mai 2012
18 juil. 2010 à 16:07
Bonjour,
merci pour la repense, mais j'arrive pas à resoudre le probleme.
j'utilise la methode Stream.BeginRead, qui va crée un autre thread pour ne pas blocké le thread en cours. après cette operation, elle va appeler la SUB ou en fait appel à la methode EndRead pour terminer l'oreration async. donc je controle pas le thread qui va etre crée, pour pouvoir "SetApartmentState". pour l'attribute <STAThread>, j'ai essayé de le metre avant le thread principal, et aussi avant la methode qui va terminer l'oreration async (ou on appelle EndRead), bref, mon thread est toujours MTA.


un exemple de mon code :
    Sub MySUB()
        'Commence l'operation async de lecture
        Stream.BeginRead(Buffer, offset, Size, New AsyncCallback(AddressOf EndReading), Nothing)
    End Sub
    Sub EndReading(ByVal ar As IAsyncResult)
        'on  termine l'operation...
        Stream.EndRead(ar)
        'la, notre thread doit etre STA, mais il est MTA...
    End Sub
0
foliv57 Messages postés 420 Date d'inscription vendredi 17 novembre 2006 Statut Membre Dernière intervention 15 juillet 2014 9
18 juil. 2010 à 21:01
Oui, malheuresement le delegate cré un thread ayant le même apartment state que le thread appelant.

Le seul moyen est de créer son propre thread pour modifier l'apartment state (donc de ne pas utiliser BeginRead). Ce qui est peut-etre meme plus judicieux si les réceptions sont nombreuse car en utilisant les delegate, a chaque réception un thread est créé puis détrui.

Ou alors de faire quelque chose de pas très correcte mais qui doit marcher :
Private Sub StartRead()
   Dim newThread As Thread = New Thread(AddressOf ThreadMethod)
   newThread.SetApartmentState(ApartmentState.STA)
   newThread.Start()
End Sub

Private Sub ThreadMethod()
    Stream.BeginRead(Buffer, offset, Size, New AsyncCallback(AddressOf EndReading), Nothing)
End Sub
0
MiharbiDoNo Messages postés 150 Date d'inscription dimanche 17 mai 2009 Statut Membre Dernière intervention 25 mai 2012
18 juil. 2010 à 22:16
elle semble bonne ta methode, mais c'est une perte de ressources, puisque on va crée un autre thread de plus a chaque lecture... et on doit le libérer aussi...
j'vais essayé de crée le main thread STA, et toutes les création de threads STA Aussi, et j'vais voir si le thread resultant est STA aussi ou non. merci foliv pour ton aide.
0
MiharbiDoNo Messages postés 150 Date d'inscription dimanche 17 mai 2009 Statut Membre Dernière intervention 25 mai 2012
18 juil. 2010 à 23:01
non, le thread qui va s'executer après le callback est toujours MTA. bizzare comment Microsoft n'as pas pensé à ça.
0
foliv57 Messages postés 420 Date d'inscription vendredi 17 novembre 2006 Statut Membre Dernière intervention 15 juillet 2014 9
18 juil. 2010 à 23:22
Ce qui est étonant aussi c'est que, par défaut, le thread principal de l'application devrait être STA.

Faite un essai en faisant un petit :
MsgBox(Thread.CurrentThread.GetApartmentState().ToString)


à l'ouverture de votre formulaire principal.
0
MiharbiDoNo Messages postés 150 Date d'inscription dimanche 17 mai 2009 Statut Membre Dernière intervention 25 mai 2012
18 juil. 2010 à 23:35
c'est exactement la methode avec laquelle j'aime verifié les propriété en temp reélle. c'est fait:
thread principal : STA
verification dans MySUB : STA (evident, même thread)
verification dans EndReading : MTA!!
j'ai meme ajouté l'attribute <STAThread> devant tout les SUB et function Qui vont etre appelés, et rien, le thread crée par l'operation async reste toujours MTA.
0
Rejoignez-nous