在静态情况下使用异步更新UI不工作
问题描述:
我使用下面的代码在静态情况下使用异步更新UI不工作
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);
}
}
}
,我想要做的就是运行的方法SendNotification
每10秒什么。为了达到这个目的,我把这个方法称为RunPeriodically
。
然而,呼叫SendNotifcation
抛出InvalidOperationException
,说:
调用线程必须为STA,因为许多UI组件都需要这个。
我也试过some suggestions使用Dispatcher
这样
private static void SendNotification(string message, BalloonIcon balloonIcon)
{
Dispatcher.CurrentDispatcher.Invoke(() =>
{
new TaskbarIcon().ShowBalloonTip("Title", message, balloonIcon);
});
}
但它并没有做出改变。
我唯一的猜测是,该代码不起作用,因为它不是从一个Window
实例调用,而是在没有this.Dispatcher
一类的静态背景下,但我不知道如何使它在这方面的工作案件和我感谢任何帮助。
答
这个稍作修改的例子对我来说工作得很好。
希望它有帮助!
public static class Program
{
private static NotifyIcon notifyIcon;
[STAThread]
public static void Main(string[] args)
{
CancellationTokenSource tokenSource = new CancellationTokenSource();
notifyIcon = new NotifyIcon();
notifyIcon.Icon = SystemIcons.Information;
notifyIcon.BalloonTipTitle = "Title";
notifyIcon.Visible = true;
Task timerTask = Program.RunPeriodically(() => { Program.SendNotification(DateTime.Now.ToString(), ToolTipIcon.Info); }, TimeSpan.FromSeconds(10), tokenSource.Token);
timerTask.Wait(tokenSource.Token);
}
private static void SendNotification(string message, ToolTipIcon balloonIcon)
{
notifyIcon.BalloonTipIcon = balloonIcon;
notifyIcon.BalloonTipText = message;
notifyIcon.ShowBalloonTip(500);
}
private static async Task RunPeriodically(Action action, TimeSpan interval, CancellationToken token)
{
while (true)
{
action();
await Task.Delay(interval, token);
}
}
}
+0
为我解决了这个问题。像魅力一样工作,谢谢! –
如果您有更新的用户界面,您*不需要*控制台应用程序。尽管不明显,Windows窗体和WPF应用程序都是从Main函数开始的。这不会让他们*控制台*应用程序 –
@PanagiotisKanavos是的,你是对的。谢谢。我将编辑问题标题以澄清这种误解。 –
至于你的具体问题,只是*不*从另一个线程更新UI。使用async/await * await *在后台运行的任何内容,并在调用await后更新UI。 'await'不会让任何东西在后台运行。它*等待后台任务/作业完成,然后返回到UI线程。当你已经在UI线程 –