Der Aufruf von
dient ja dazu, den angegebenen Code (in deinem Fall das Starten des
Storyboards) im GUI-Thread auszuführen. D.h. auch dein
wird im GUI-Thread ausgeführt, was diesen dann blockiert.
Für gewöhnlich führt man alle lang andauernden Operationen (in deinem
Fall vermutlich das Laden eines Bildes aus irgendeiner Quelle) in einem
Hintergrundthread durch. Wenn die Daten dann vollständig geladen sind,
aktualisiert man die GUI. Das entspricht ja schon mal deinem Vorgehen,
das passt also soweit.
Natürlich muss man darauf achten, dass man die Operationen, die im
GUI-Thread laufen, so kurz wie möglich hält.
Im Code ausgedrückt:
1 | public async Task FadeImage()
|
2 | {
|
3 | await Task.Run(() =>
|
4 | {
|
5 | // Zeitintensive Operationen hier ausführen
|
6 | Thread.Sleep(5000);
|
7 |
|
8 | StFadeIn.Dispatcher.Invoke(new Action(() =>
|
9 | {
|
10 | // Hier nur noch die GUI aktualisieren
|
11 | StFadeIn.Begin(bild);
|
12 | }));
|
13 | });
|
14 | }
|
Lisa schrieb:
> aber
> ich will auch nicht, dass die App hängt, wenn ich 2 Sekunden fade oder
> so
In diesem konkreten Beispiel gilt: WPF kümmert sich schon darum, dass
die Anwendung während des Fadens weiterhin reagiert (probiers einfach
mal aus, indem du Zeit im Storyboard erhöhst).
Ohne jetzt zu tief ins Detail gehen zu wollen: Man kann das erreichen
indem man die lang andauernde Operation immer wieder kurz "unterbricht"
und die MessageQueue abarbeitet. Aus persönlicher Erfahrung rate ich dir
die Finger davon zu lassen. So etwas sorgt in regelmäßigen Abständen für
die kuriosesten Bugs (muss beruflich selbst eine Anwendung betreuen, in
der so etwas gemacht wird ;-)).
Daher gilt (wie oben schon geschrieben): Lang dauernde Operationen im
Hintergrundthread durchführen und dann nur noch die GUI aktualisieren.
Lisa schrieb:
> was ist der Unterschied zwischen
>
>> var t = new Task(() =>
>> t.Start();
> UND
>> await Task.Run(() =>
>
> => Wobei auch hier genau das selbe Ergebnis herauskommt... vermutlich
> nur eine andere "Schreibweise"???
Zum einen startet das den Task und entspricht damit dem ersten Code. Das
await (was übrigens nur in Methoden verwendet werden kann, die als async
gekennzeichnet sind), wartet aber auch bis der Task abgeschlossen ist.
Das heißt, Code der nach dem mit await gekennzeichneten Aufruf kommt,
wird erst ausgeführt, wenn der Task abgearbeitet ist:
1 | private async void Test()
|
2 | {
|
3 | await Task.Run(() => Thread.Sleep(5000));
|
4 |
|
5 | MessageBox.Show("Diese MessageBox wird erst nach 5 Sekunden angezeigt.");
|
6 | }
|
Während das async auf die Beendigung des Tasks wartet, wird die
Kontrolle übrigens an den Aufrufer der asynchronen Methode
zurückgegeben:
1 | private void MyMethod()
|
2 | {
|
3 | Test();
|
4 |
|
5 | MessageBox.Show("Diese MessageBox wird sofort angezeigt.");
|
6 | }
|
7 |
|
8 | private async void Test()
|
9 | {
|
10 | await Task.Run(() => Thread.Sleep(5000));
|
11 |
|
12 | MessageBox.Show("Diese MessageBox wird erst nach 5 Sekunden angezeigt.");
|
13 | }
|