2016-06-05 7 views
-1

Dies ist der Code, ich möchte mein Formular am Leben bleiben beim Herunterladen von Code aus dem Internet und wenn es fertig ist Ich möchte HTML-Container aktualisieren. Wenn ich dieses Formular einfriere. Ich bin neu zu threading und tasking und ich brauche wenig Hilfe. Vielen Dank!Cross thread Ausnahme Windows Forms C#

private void buttonGetHTML_Click(object sender, EventArgs e) 
    { 
     Task.Run(() => Download(textBoxUrl.Text)).ContinueWith((Download) => htmlContent.Text = Download.Result); 
    } 

    private string Download(string url) 
    { 
     using (WebClient client = new WebClient()) 
     { 
      string context = client.DownloadString(url); 
      return context; 
     } 
    } 
+0

'ContinueWith' ist alten Stil. Async/erwarten ist viel einfacher zu lesen, zu schreiben und zu verstehen. Es ist nur ein Wrapper, warum nicht benutzen. – niksofteng

Antwort

4

verwenden:

private async void buttonGetHTML_Click(object sender, EventArgs e) 
{ 
    using (WebClient client = new WebClient()) 
    { 
     string context = await client.DownloadStringAsync(textBoxUrl.Text); 
     htmlContent.Text = content 
    } 
} 

Die meisten Menschen versuchen, dies mit Control.Invoke oder etwas zu lösen (Link in Kommentar sehen), aber in diesem Fall gibt es eine bessere Option. Verwenden der Async-Methoden der Klasse WebClient. Siehe https://msdn.microsoft.com/en-us/library/system.net.webclient.downloadstringasync(v=vs.110).aspx

Suchen Sie immer zuerst nach Async-Methoden, bevor Sie stattdessen einen eigenen Thread erstellen.

Wenn Sie nicht verwenden können async await versuchen Sie dies:

private void buttonGetHTML_Click(object sender, EventArgs e) 
{ 
    var url = textBoxUrl.Text; 
    Task.Run(() => Download(url)).ContinueWith((Download) => { htmlContent.Text = Download.Result; }, TaskScheduler.FromCurrentSynchronizationContext()); 
} 

private string Download(string url) 
{ 
    using (WebClient client = new WebClient()) 
    { 
     string context = client.DownloadString(url); 
     return context; 
    } 
} 

So ist der Anruf, der die Benutzeroberfläche zugreift, ist die Aufgabe aus und der Fortsetzung, die die Benutzeroberfläche greift auf dem UI-Thread ausgeführt werden.

+0

Ja, das funktioniert, aber ich muss es ohne warten und async tun, und ich habe Probleme ... –

+1

Nur um klar zu sein, warum können Sie nicht async/erwarten? –

+0

Ich erhalte diesen Fehler http://i68.tinypic.com/rvlxk0.jpg Ich kann async nicht verwenden/erwarten, dass dies Aufgabe von der Universität ist, ohne async/await –

2

Der Grund ist textBoxUrl.Text von Nicht-UI-Thread aufrufen. Versuchen Sie, den Text zuerst abzurufen, und rufen Sie dann Task.Run:

private void buttonGetHTML_Click(object sender, EventArgs e) 
{ 
    var url = textBoxUrl.Text; 
    Task.Run(() => Download(url)).ContinueWith((Download) => htmlContent.Text = Download.Result); 
}