C# 同样是UI线程和计时器
我有一个代码部分,从服务器调用一些XML数据。有时网络或服务器本身出现错误。所以我需要一些错误处理。 为此,我安装了AwesomeFonts.WPF并创建了一个简单的C# 同样是UI线程和计时器,c#,wpf,ui-thread,C#,Wpf,Ui Thread,我有一个代码部分,从服务器调用一些XML数据。有时网络或服务器本身出现错误。所以我需要一些错误处理。 为此,我安装了AwesomeFonts.WPF并创建了一个简单的 <StackPanel Name="ErrorPanel" Height="200" Width="300" Visibility="Hidden" Canvas.Top="440" Canvas.Left="810" Panel.ZIndex="9999"> <fa:ImageAweso
<StackPanel Name="ErrorPanel" Height="200" Width="300" Visibility="Hidden" Canvas.Top="440" Canvas.Left="810" Panel.ZIndex="9999">
<fa:ImageAwesome Icon="Spinner" Spin="True" Height="100" Width="100" />
<TextBlock Text="data loading..." />
</StackPanel>
现在我知道WPF的调度问题,并且已经尝试过类似的方法
Application.Current.Dispatcher.Invoke(() => { ErrorPanel.Visibility = Visibility.Visible; });
Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new
ThreadStart(delegate
{
ErrorPanel.Visibility = Visibility.Visible;
}));
或者类似的事情
Application.Current.Dispatcher.Invoke(() => { ErrorPanel.Visibility = Visibility.Visible; });
Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new
ThreadStart(delegate
{
ErrorPanel.Visibility = Visibility.Visible;
}));
在这一次,我确实看到了面板,但动画停止了。我想让计时器运行,这样我可以缩短服务器的超时时间。我想做一些更像:
1的事情。显示动画
2。启动计时器
3。呼叫服务器
4。数到10
5。如果我直到10点才得到答案,则显示错误消息,否则显示结果
6。隐藏等待的动画。
有人知道如何实现这一点吗?您应该在后台线程上执行
GetProductList
方法
async void Click(object sender, RoutedEventArgs e)
{
ErrorPanel.Visibility = Visibility.Visible;
var products = await Task.Run(() => Communication.GetProductList(tempPznList));
mainPznItem.SubPzns = products;
ErrorPanel.Visibility = Visibility.Hidden;
}
这是很重要的一部分,因为UI线程不能同时处理输入事件和执行方法
如果愿意,您还可以启动计时器。大概是这样的:
DispatcherTimer _timer;
bool cancelled;
async void Click()
{
if (_timer != null)
{
_timer.Stop();
_timer.Dispose();
}
ErrorPanel.Visibility = Visibility.Visible;
_timer = new DispatcherTimer();
_timer.Interval = TimeSpan.FromSeconds(10);
_timer.Tick += _timer_Tick;
_timer.Start();
var products = await Task.Run(() => Communication.GetProductList(tempPznList));
_timer.Stop();
if (!cancelled)
{
mainPznItem.SubPzns = products;
ErrorPanel.Visibility = Visibility.Hidden;
}
}
private void _timer_Tick(object sender, EventArgs e)
{
MessageBox.Show("error...");
_timer.Tick -= _timer_Tick;
_timer.Stop();
cancelled = true;
ErrorPanel.Visibility = Visibility.Hidden;
}
使您的
GetProductList()
异步,最好使用异步webrequest(HttpClient),第二个选择是使用Task.Run()。是的,但这只是因为我们不了解GetProductList()。如果它能够获得一个取消令牌,那么整个计时器就可能被丢弃。Task.Run()也是权宜之计。该解决方案非常有效。我应该再看看这整个等待任务的事情。。。直到现在还没有完全理解它。