在静态上下文中使用异步更新 UI 不起作用
Using async in static context to update the UI is not working
我正在使用以下代码
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);
}
}
}
我想做的是 运行 每 10 秒 SendNotification
方法。为此,我调用方法 RunPeriodically
.
然而,对 SendNotifcation
的调用抛出一个 InvalidOperationException
,说:
The calling thread must be STA, because many UI components require this.
我也试过 像这样使用 Dispatcher
private static void SendNotification(string message, BalloonIcon balloonIcon)
{
Dispatcher.CurrentDispatcher.Invoke(() =>
{
new TaskbarIcon().ShowBalloonTip("Title", message, balloonIcon);
});
}
但它并没有做出改变。
我唯一的猜测是代码不起作用,因为它不是从 Window
实例调用的,而是在没有 this.Dispatcher
的 class 的静态上下文中调用的,但我不知道如何让它在这种情况下工作,非常感谢您的帮助。
下面这个稍微修改过的例子对我来说效果很好。
希望对您有所帮助!
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);
}
}
}
我正在使用以下代码
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);
}
}
}
我想做的是 运行 每 10 秒 SendNotification
方法。为此,我调用方法 RunPeriodically
.
然而,对 SendNotifcation
的调用抛出一个 InvalidOperationException
,说:
The calling thread must be STA, because many UI components require this.
我也试过 Dispatcher
private static void SendNotification(string message, BalloonIcon balloonIcon)
{
Dispatcher.CurrentDispatcher.Invoke(() =>
{
new TaskbarIcon().ShowBalloonTip("Title", message, balloonIcon);
});
}
但它并没有做出改变。
我唯一的猜测是代码不起作用,因为它不是从 Window
实例调用的,而是在没有 this.Dispatcher
的 class 的静态上下文中调用的,但我不知道如何让它在这种情况下工作,非常感谢您的帮助。
下面这个稍微修改过的例子对我来说效果很好。
希望对您有所帮助!
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);
}
}
}