2011-03-23 5 views
3

J'ai vu une discussion autour de ce sujet et j'ai conclu que ce n'est pas possible. Je devrais utiliser des Threads, le rendre STA et quand j'ai besoin de résultat, rejoindre le thread principal avec le fil créé. Cela peut fonctionner mais ce n'est pas une solution idéale car en utilisant des délégués je peux obtenir un comportement asynchrone pur (en utilisant le rappel). Donc, à la case départ - juste avant de commencer à implémenter ma propre classe Future (comme en Java); Y a-t-il un meilleur moyen d'y parvenir en utilisant des délégués?Comment faire un thread de délégué STA


    private delegate String DelegateFoo(String[] input); 
    private String Foo(String[] input){ 
     // do something with input 
     // this code need to be STA 
     // below code throws exception .. that operation is invalid 
     // Thread.CurrentThread.SetApartmentState(ApartmentState.STA) 
     return "result"; 
    } 

    private void callBackFoo(IAsyncResult iar){ 
     AsyncResult result = (AsyncResult)iar; 
     DelegateFoo del = (DelegateFoo)result.AsyncDelegate; 
     String result = null; 
     try{ 
      result = del.EndInvoke(iar); 
     }catch(Exception e){ 
      return;   
     } 

     DelegateAfterFooCallBack callbackDel = new DelegateAfterFooCallBack (AfterFooCallBack); 
     // call code which should execute in the main UI thread. 
     if (someUIControl.InvokeRequired) 
     { // execute on the main thread. 
     callbackDel.Invoke(); 
     } 
     else 
     { 
     AfterFooCallBack(); 
     } 
    } 
    private void AfterFooCallBack(){ 
     // should execute in main UI thread to update state, controls and stuff 
    } 

Répondre

4

Ce n'est pas possible. La méthode BeginInvoke() d'un délégué utilise toujours un thread threadpool. Et les threads TP sont toujours MTA, cela ne peut pas être changé. Pour obtenir un thread STA, vous devez créer un Thread et appeler sa méthode SetApartmentState() avant de le démarrer. Ce thread doit également pomper une boucle de message, Application.Run(). L'objet COM ne l'utilise que lorsque son instance a été créée dans ce thread.

Vous ne savez pas ce que vous essayez de faire, mais essayer de multi-thread un morceau de code qui n'est pas thread-safe ne peut tout simplement pas fonctionner. COM applique cela.

+0

En fait, je veux accéder aux API Watin à partir de mon application Winform. Presque toutes les API exposées par Watin nécessitent que la bande de roulement soit en STA. Je veux ouvrir une fenêtre IE dans un thread différent de mon thread UI principal. – karephul

+0

Cochez cette réponse: http://stackoverflow.com/questions/4269800/c-webbrowser-control-in-a-new-thread/4271581#4271581 –

+0

Oh, merci Hans !! c'est presque ce que je cherchais :) :) Donc j'utilise Threads, en le mettant sur STA et en définissant un EVENT pour le rendre pur Asynchrone (avec callback) .. C# rocks – karephul

Questions connexes