2009-08-21 6 views
3

Puis-je faire une fonction commeC# fonctions de fil

public void myfunc() 
{ 
    //some processing 
} 

fonction de fil par

Thread t = new Thread (new ThreadStart (myfunc)); 

puis d'autres où

t.Start(); 

et puis-je passer tout type d'arguments que ?

+0

S'il vous plaît être plus descriptif dans votre question –

+0

Vous voulez faire le paramètre délégué cteur ThreadStart() de type void MyFunc (void)? – cwap

+0

Cochez ici: [http://www.yoda.arachsys.com/csharp/threads/parameters.shtml](http://www.yoda.arachsys.com/csharp/threads/parameters.shtml) Ou ici, en utilisant le pool de threads: [http://www.yoda.arachsys.com/csharp/threads/threadpool.shtml](http://www.yoda.arachsys.com/csharp/threads/threadpool.shtml) –

Répondre

6

En théorie, vous pouvez exécuter n'importe quelle méthode dans un thread distinct, à condition de respecter certaines règles (par exemple, la synchronisation, invoquer des délégués pour mettre à jour l'interface utilisateur, etc.). De votre question, je comprends que vous n'avez pas beaucoup d'expérience avec la programmation multi-thread, je vous conseille donc de lire beaucoup sur le threading et d'apprendre les dangers et les problèmes qui peuvent survenir. Vous pouvez également utiliser la classe de travailleurs en arrière-plan qui prend certaines de vos responsabilités.

Aussi, oui, vous pouvez passer des paramètres à une méthode de fil:

private class ThreadParameters 
{ 
    .... 
} 

... 

public void ThreadFunc(object state) 
{ 
    ThreadParameters params = (ThreadParameters)state; 
    .... 
} 

Thread t = new Thread(new ParameterizedThreadStart(ThreadFunc)); 
t.Start(new ThreadParameters() { ... }); 
7

Il y a une surcharge qui accepte un état d'objet - cependant, OMI la meilleure façon de transmettre des arguments arbitraires à un ThreadStart (et vérifier la signature au moment de la compilation) est une méthode anonyme:

int a = ... 
string b = ... 
Thread t = new Thread (delegate() { SomeFunction(a,b);}); 

Just (ce qui est importante) - * ne changent pas a ou b après cela, comme le changement se refléter sur le fil (comme une course) - à savoir ne pas faire: d'introduire des variables supplémentaires pour ce

int a = ... 
string b = ... 
Thread t = new Thread (delegate() { SomeFunction(a,b);}); 
a = 12; // this change will be visible to the anonymous method - be careful ;-p 

Dans le cas des boucles, il est important (quand sur des variables et capturées async); ceux-ci sont très différentes

int[] data = {1,2,3,4,5}; 
    foreach(int i in data) { 
     ThreadPool.QueueUserWorkItem(delegate { 
      Console.WriteLine(i); }); 
    } 
    Console.ReadLine(); 

(qui sera probablement imprimer 5,5,5,5,5)

int[] data = {1,2,3,4,5}; 
    foreach (int i in data) { 
     int tmp = i; 
     ThreadPool.QueueUserWorkItem(delegate { 
      Console.WriteLine(tmp); }); 
    } 
    Console.ReadLine(); 

(qui imprimera 1-5 sans ordre particulier)


Mise à jour pour discuter du point de Meeh (commentaires); qu'est-ce que cette impression (99,999% du temps - il y a une condition de concurrence)?

string s = "dreams"; 
    ThreadPool.QueueUserWorkItem(delegate { 
     Console.WriteLine(s); 
    }); 
    s = "reality"; 
    Console.ReadLine(); 
+0

Vous pouvez évitez le cast si vous lui dites explicitement que le délégué n'a aucun paramètre, c'est-à-dire le nouveau Thread (delegate() {SomeFunction (a, b);}) –

+0

Tidied, acclame. –

+0

Erm, ne sont pas int un type de valeur et donc, étant passé par valeur? Changer un après que le fil a été créé ne changera pas la valeur reçue par le fil, ou ai-je tort? La même chose vaut pour la chaîne, bien que ce soit un type de référence - Donc, tout ce que vous changeriez serait la portée b-handle des étendues locales. Utiliser SomeFunction (ref a, ref b) ferait ce que vous avez dit .. Je ne suis pas tout à fait sûr cependant, je vérifie habituellement des trucs comme ça brièvement à la volée :) – cwap

1
protected void Page_Load(object sender, EventArgs e) 
    { 
     if (Session["intCompany_Accounting_Year_ID"] == null || Session["vcrAdmin_Id"] == null) 
     { 
      Response.Redirect("User_Login.aspx"); 
     } 

     if (!IsPostBack) 
     { 
      ViewState["Page_Index"] = Request.QueryString["Page_Index"]; 
      ViewState["ID_Field"] = Request.QueryString["ID_Field"]; 
      Initialize_Page();     
      Bind_Search_Grid();     
     } 
    } 
    protected void btnFind_Click(object sender, EventArgs e) 
    { 
     Bind_Search_Grid(); 
    }        




protected void grdSearch_Result_RowDataBound(object sender, GridViewRowEventArgs e) 
{ 
    if (e.Row.RowType == DataControlRowType.Header) 
    { 
     Label lblHeader = (Label)e.Row.FindControl("lblHeader"); 
     lblHeader.Text = ViewState["Header_Name"].ToString(); 
    } 
    else if (e.Row.RowType == DataControlRowType.DataRow) 
    { 
     LinkButton lnk = (LinkButton)e.Row.FindControl("lnkDisplay_Text"); 
     lnk.OnClientClick = "Close_Window('" + lnk.CommandArgument + "','" + ViewState["ID_Field"].ToString() 
      + "')"; 
    } 

} 
protected void grdSearch_Result_RowCreated(object sender, GridViewRowEventArgs e) 
{ 
    e.Row.Cells[1].Visible = false; 
    e.Row.Cells[2].Visible = false; 
    e.Row.Cells[3].Visible = false; 
} 

} 
+0

Aviez-vous cette réponse pour une question différente? Je ne vois pas comment ce code se rapporte à la question. –