J'utilise le code suivantEn utilisant async dans le contexte statique pour mettre à jour l'interface utilisateur ne fonctionne pas
public static class Program
{
[STAThread]
public static void Main(string[] args)
{
CancellationTokenSource tokenSource = new CancellationTokenSource();
Task timerTask = Program.RunPeriodically(() => { Program.SendNotification($"foo", BalloonIcon.Info); }, TimeSpan.FromSeconds(10), tokenSource.Token);
timerTask.Wait(tokenSource.Token);
}
private static void SendNotification(string message, BalloonIcon balloonIcon)
{
new TaskbarIcon().ShowBalloonTip("Title", message, balloonIcon);
}
private static async Task RunPeriodically(Action action, TimeSpan interval, CancellationToken token)
{
while (true)
{
action();
await Task.Delay(interval, token);
}
}
}
et ce que je veux faire est de lancer la méthode SendNotification
toutes les 10 secondes. Pour ce faire, j'appelle la méthode RunPeriodically
.
Cependant, l'appel à SendNotifcation
jette un InvalidOperationException
, en disant:
Le thread appelant doit être STA, parce que de nombreux composants de l'interface utilisateur exigent.
J'ai aussi essayé some suggestions utilisant le Dispatcher
comme celui-ci
private static void SendNotification(string message, BalloonIcon balloonIcon)
{
Dispatcher.CurrentDispatcher.Invoke(() =>
{
new TaskbarIcon().ShowBalloonTip("Title", message, balloonIcon);
});
}
mais il n'a pas fait un changement. Ma seule supposition est que le code ne fonctionne pas car il n'est pas appelé à partir d'une instance Window
, mais plutôt dans un contexte statique d'une classe qui n'a pas this.Dispatcher
, mais je ne sais pas comment le faire fonctionner dans ce cas et j'apprécie toute aide.
Vous * n'avez * pas * d'application de console si vous avez une interface utilisateur à mettre à jour. Les applications Windows Forms et WPF commencent à partir d'une fonction Main, même si elle n'est pas apparente. Cela ne fait pas les applications * console * –
@PanagiotisKanavos oui, vous avez raison. Je vous remercie. Je vais modifier le titre de la question pour effacer cette idée fausse. –
En ce qui concerne votre problème spécifique, juste * ne pas * mettre à jour l'interface utilisateur à partir d'un autre thread. Utilisez async/await pour * attendre * tout ce qui s'exécute en arrière-plan et mettez à jour l'interface utilisateur après l'appel de 'await'. 'await' ne fait rien tourner en arrière-plan. Il * attend * qu'une tâche d'arrière-plan/travail se termine, puis retourne au thread d'interface utilisateur. Vous n'avez pas besoin de dispatchers et de 'Invoke()' lorsque vous êtes déjà sur le thread d'interface utilisateur –