C# 在静态上下文中使用异步更新UI不起作用
我正在使用以下代码C# 在静态上下文中使用异步更新UI不起作用,c#,asynchronous,task,sta,C#,Asynchronous,Task,Sta,我正在使用以下代码 public static class Program { [STAThread] public static void Main(string[] args) { CancellationTokenSource tokenSource = new CancellationTokenSource(); Task timerTask = Program.RunPeriodically(() => { Program
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
。为了实现这一点,我调用方法runperiodic
但是,调用sendNotification
会抛出一个InvalidOperationException
,说明:
调用线程必须是STA,因为许多UI组件都需要它
我还试着像这样使用调度器
private static void SendNotification(string message, BalloonIcon balloonIcon)
{
Dispatcher.CurrentDispatcher.Invoke(() =>
{
new TaskbarIcon().ShowBalloonTip("Title", message, balloonIcon);
});
}
但这并没有改变
我唯一的猜测是代码不起作用,因为它不是从窗口
实例调用的,而是在没有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);
}
}
}
如果要更新UI,则没有控制台应用程序。Windows窗体和WPF应用程序都从一个主函数开始,尽管它并不明显。这并不能让他们感到安慰applications@PanagiotisKanavos是的,你说得对。非常感谢。我将编辑问题标题以消除误解。至于您的具体问题,请不要从其他线程更新UI。使用async/await等待后台运行的任何内容,并在调用await
后更新UI<代码>等待
不会在后台运行任何内容。它等待后台任务/作业完成,然后返回UI线程。当您已经在UI上时,不需要dispatchers和Invoke()
thread@PanagiotisKanavos那么什么时候是调用该方法的合适位置呢?在timerTask.Wait之后(tokenSource.Token)代码>?看起来像一个XY问题。当你只需要一个无窗口的程序来显示通知时,谷歌就可以了。不要发明你自己的。这为我解决了它。很有魅力,谢谢!