[英]C# WPF Dispatcher Timer Tick in Separate Thread
So I have a basic WPF application, that OnStartup
creates a DispatcherTimer
and has a tick method that runs a basic SQL query to check the status of some arbitrary table.所以我有一个基本的 WPF 应用程序,它
OnStartup
创建一个DispatcherTimer
并有一个运行基本 SQL 查询的滴答方法来检查一些任意表的状态。
It is a variable query in terms of how long it takes to execute.就执行所需的时间而言,这是一个可变查询。
If I am in the main application window, when the background DispatcherTimer
runs ( DispatcherTimer
code being within the App.xaml
, not the MainWindow.xaml
), the window hangs while the query runs, and as the query runs every 5 seconds, the GUI is unresponsive. If I am in the main application window, when the background
DispatcherTimer
runs ( DispatcherTimer
code being within the App.xaml
, not the MainWindow.xaml
), the window hangs while the query runs, and as the query runs every 5 seconds, the GUI没有反应。
It seems a new thread is the way to go, but I am lost on where to begin.似乎一个新线程是通往 go 的方式,但我不知道从哪里开始。 I am relatively new to C#/WPF so it's all a learning curve at the moment.
我对 C#/WPF 比较陌生,所以目前这只是一个学习曲线。 How would I go about invoking my
dispatcherTimer_Tick
within a new thread, to avoid this problem?我将如何 go 在新线程中调用我的
dispatcherTimer_Tick
以避免这个问题?
DispatcherTimer dispatcherTimer;
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
MainWindow = new MainWindow();
MainWindow.Closing += MainWindow_Closing;
_notifyIcon = new System.Windows.Forms.NotifyIcon();
_notifyIcon.DoubleClick += (s, args) => ShowMainWindow();
_notifyIcon.Icon = BackgroundApplication.Properties.Resources.GTL;
_notifyIcon.Visible = true;
CreateContextMenu();
dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Interval = new TimeSpan(0, 0, 5);
dispatcherTimer.Start();
}
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
// Console.WriteLine("Tick");
SqlConnection cnn;
connectionString = @"SOME_DATA_SOURCE";
cnn = new SqlConnection(connectionString);
cnn.Open();
// MessageBox.Show("Connection Open !");
// cnn.Close();
SqlCommand command;
SqlDataReader dataReader;
String sql = "";
Int16 output = 0;
sql = "SOME SQL STATEMENT";
command = new SqlCommand(sql, cnn);
dataReader = command.ExecuteReader();
while (dataReader.Read())
{
output = Int16.Parse(dataReader[""].ToString());
}
if(output > 0)
{
_notifyIcon.Icon = BackgroundApplication.Properties.Resources.RTL;
}
_notifyIcon.Text = "Current Issues: " + output;
}
Make the Tick handler async and await the long-running call:使 Tick 处理程序异步并等待长时间运行的调用:
private async void dispatcherTimer_Tick(object sender, EventArgs e)
{
await Task.Run(() =>
{
// make query here
});
// update the UI outside the Task
_notifyIcon.Text = "Current Issues: " + output;
}
Even better would be to directly call async methods, like更好的是直接调用异步方法,比如
private async void dispatcherTimer_Tick(object sender, EventArgs e)
{
...
dataReader = await command.ExecuteReaderAsync();
...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.