2016-10-06 2 views
0

I-Code haben wie folgt:Zugriff auf UI-Objekte während Filestream C#

private void btnCovert_Click(object sender, EventArgs e) 
{ 
    //get file 
    string blfrpath = txtPath.Text; 
    byte[] b = new byte[108]; 
    //ASCIIEncoding ascii = new ASCIIEncoding(); 
    string blfObjstr; 
    long filesize; 
    long numObjs; 
    int i; 

    using (FileStream fs = File.Open(blfrpath, FileMode.Open)) 
    { 
     filesize = fs.Length; 
     numObjs = filesize/56; 
     i = 0; 
     while (fs.Read(b, 0, b.Length) > 0) 
     { 
      blfObjstr = Encoding.ASCII.GetString(b); 
      lstData.Items.Add(blfObjstr); 
      prbConvert.Value = (i/(int)numObjs)*100; 
      i++; 
     } 
    } 
} 

Problem ist, wenn die Schaltfläche nicht das Listenfeld geklickt wird gerade aktualisiert jeder Iteration oder der Fortschrittsbalken Erhöhung der Form einzufrieren scheint und erscheinen während der ganzen ~ 30 Sekunden zum Absturz zu bringen. Wie kann ich das verhindern?

ich unter Verwendung der Aufgabe versuchte, dieses (und machte das Click-Ereignis async) bis zum Ende des Hinzufügen

  Task<int> task = updateUI(blfObjstr, i, (int)numObjs); 
      int result = await task; 
     } 

} 

private async Task<int> updateUI(string listStr, int probNum,int prbDenom) 
{ 
    prbConvert.Value = (probNum/prbDenom) * 100; 
    lstData.Items.Add(listStr); 
    return 1; 
} 

ich versucht habe, einen Hintergrund Arbeiter Hinzufügen beide nur einfach: mit den Update Sachen in einem Hintergrund Arbeitnehmer. aber ich bekomme nur "diese Hintergrund-Worker ist schon beschäftigt" auf der zweiten Iteration, auch wenn ich es als ein Argument, wenn ich es ausführen.

Ich habe versucht, die ganze Sache in einem Hintergrundeditor und dann die Aktualisierung in einem Bericht Fortschrittsanruf tun, aber das funktioniert auch nicht.

danke

Antwort

0

Sie verwenden Haupt-UI-Thread für lange Berechnungen. Der UI-Thread ist verantwortlich für die Aktualisierung der Benutzeroberfläche. Wenn Sie die Anwendung also lange Zeit blockieren, wird Ihre App eingefroren. Einstellung Eigenschaft wie prbConvert.Value nicht direkt UI aktualisieren es nur Nachricht für UI-Thread zu aktualisieren UI später generieren.

Sie können Datei auf anderen Thread mit Aufgabe lesen tun:

private async void btnCovert_Click(object sender, EventArgs e) 
{ 
    //get file 
    string blfrpath = txtPath.Text; 
    byte[] b = new byte[108]; 
    //ASCIIEncoding ascii = new ASCIIEncoding(); 
    string blfObjstr; 
    long filesize; 
    long numObjs; 
    int i; 

    using (FileStream fs = File.Open(blfrpath, FileMode.Open)) 
    { 
     filesize = fs.Length; 
     numObjs = filesize/56; 
     i = 0; 
     while (await Task<int>.Factory.FromAsync(fs.BeginRead, fs.EndRead, b, 0, b.Length, null) > 0) 
     { 
      blfObjstr = Encoding.ASCII.GetString(b); 
      lstData.Items.Add(blfObjstr); 
      prbConvert.Value = (i/(int)numObjs)*100; 
      i++; 
     } 
    } 
} 

Es gibt mehr Möglichkeiten, wie diese gelöst werden, kann dies nur einer von ihnen ist, andere Background Klasse sein könnte oder eigenen Thread verwenden und rufe um die Benutzeroberfläche zu aktualisieren.