2017-09-28 69 views
0

我使用下面的代碼在靜態情況下使用異步更新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一類的靜態背景下,但我不知道如何使它在這方面的工作案件和我感謝任何幫助。

+1

如果您有更新的用戶界面,您*不需要*控制檯應用程序。儘管不明顯,Windows窗體和WPF應用程序都是從Main函數開始的。這不會讓他們*控制檯*應用程序 –

+0

@PanagiotisKanavos是的,你是對的。謝謝。我將編輯問題標題以澄清這種誤解。 –

+0

至於你的具體問題,只是*不*從另一個線程更新UI。使用async/await * await *在後臺運行的任何內容,並在調用await後更新UI。 'await'不會讓任何東西在後臺運行。它*等待後臺任務/作業完成,然後返回到UI線程。當你已經在UI線程 –

回答

1

這個稍作修改的例子對我來說工作得很好。

希望它有幫助!

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

爲我解決了這個問題。像魅力一樣工作,謝謝! –