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问题。当你只需要一个无窗口的程序来显示通知时,谷歌就可以了。不要发明你自己的。这为我解决了它。很有魅力,谢谢!