2012-06-12 6 views
0

Ici, j'utilise une logique simple en C#. Je soustrais des jours de deux DateTimePicker s et générant le même nombre de lignes GridView que le nombre total de jours. Je mets cette logique dans un Timer, qui ticks à un intervalle de 100 millisecondes et s'exécute automatiquement. Cela fonctionne bien pour 90-100 lignes, mais si cela va à 1000 lignes, le programme reste bloqué. Donc, je pense que je dois utiliser des discussions. Comment puis-je faire ceci? Je sais multithreading de base, et a essayé ce qui n'a pas fonctionné:Mises à jour GridView multithread

private void timer1_Tick(object sender, EventArgs e) 
{ 
    myMethod(); 
} 

void myMethod() { 
    ed_Picker.MinDate = sd_Picker.Value; 
    TimeSpan ts = new TimeSpan(); 

    //GridView.Rows.cont 

    label3.Text = ed_Picker.Value.CompareTo(sd_Picker.Value).ToString(); 
    //dateTimePicker2.MinDate = dateTimePicker1.Value; 

    ts = ed_Picker.Value.Subtract(sd_Picker.Value); 
    double d; 

    d = Math.Ceiling(ts.TotalDays) + 1; 
    label3.Text = d.ToString(); 
    DataGridViewRow row = new DataGridViewRow(); 


    GridView.RowCount = Int32.Parse(d.ToString()); // This is key line which I like to put in new Thread 
    for (int i = 1; i <= GridView.RowCount; i++) 
    { 
     GridView.Rows[i - 1].Cells[0].Value = sd_Picker.Value.AddDays(Convert.ToDouble(i - 1)).ToLongDateString(); 
     GridView.Rows[i - 1].Cells[0].ReadOnly = true; 
    } 
    DateTimeConverter dtc = new DateTimeConverter(); 
    TimeSpan ts1 = new TimeSpan(); 

    try 
    { 
     for (int i = 0; i < GridView.RowCount; i++) 
     { 
      ts1 += Convert.ToDateTime(GridView.Rows[i].Cells[2].Value).Subtract(Convert.ToDateTime(GridView.Rows[i].Cells[1].Value)); 
     } 
    } 
    catch (Exception ex) 
    { 

    } 

    label6.Text = ts1.ToString(); 
} 
+3

Qu'essayez-vous de faire? L'histoire nous aide à comprendre l'intrigue. De toute façon, vous devriez probablement lire à propos de BackgroundWorkers [ici] (http://www.dotnetperls.com/backgroundworker) et [ici] (http://msdn.microsoft.com/fr-fr/library/cc221403 (v = vs.95) .aspx). – SimpleVar

+0

ok, je veux créer un nouveau fil Donc, que même s'il y a 10K lignes, il veut déranger le programme principal, et courir derrière la scène. –

+0

@YoryeNathan: J'ai essayé d'utiliser Bcakgroundworkers, mais en obtenant la même erreur: "InvalidOperationException - Opération inter-thread non valide: Contrôle 'ed_Picker' accédé à partir d'un thread autre que le thread sur lequel il a été créé." cette erreur est sur la première ligne de la méthode myMethod. –

Répondre

0

Voici l'idée générale de la façon d'utiliser BackgroundWorker pour faire du fil et mettre à jour l'interface utilisateur:

var worker = new BackgroundWorker {WorkerReportsProgress = true}; 
worker.DoWork += this.ThreadWorkMethod; 
worker.ProgressChanged += this.ThreadProgressMethod; 
worker.RunWorkerAsync(); 

... 

private void ThreadWorkMethod(object sender, DoWorkEventArgs e) 
{ 
    var worker = (BackgroundWorker)sender; 

    for (int i = 0; i = 1000; i++) 
    { 
     // Time consuming operation 
     Thread.Sleep(1000); 

     worker.ReportProgress(i * 100d/1000, i); 
    } 
} 

private void ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    // Here you can access controls, etc. 

    if (e.Progresspercentage == 100) 
    { 
     this.progLabel.Text = "100% Done"; 
    } 
    else 
    { 
     this.progLabel.Text = string.Format("{0}% ({1}/1000)", 
              e.ProgressPercentage, 
              e.UserState); 
    } 
} 

Et si vous voulez également écouter l'événement RunWorkerCompleted - vous pouvez également accéder aux contrôles à partir de là, etc.

Ainsi, la méthode DoWork consiste à effectuer le travail par thread et à appeler ReportProgress afin de pouvoir modifier l'interface utilisateur de manière appropriée chaque fois que le besoin vient. L'événement RunWorkerCompleted sera appelé automatiquement lorsque la méthode DoWork est terminée (retourne ou se termine).

Questions connexes