异步方法并返回IAsyncResult [英] Async Methds and returning IAsyncResult
问题描述
我正在尝试确定显示某些移动文本(如处理中")的最佳方法. 处理中....."等等(在其他作业正在运行时,点会变长.)
我想调用this.AnotherMethod,让它启动,虽然需要4秒钟,但我希望mybtn_Click中的while循环更新标签值.然后,当4秒完成时,endinvoke设置result.IsCompleted并循环 停止.
此代码是否仍接近我需要的代码?任何帮助将不胜感激.我已经使用全局布尔值来做到这一点,但是我发现使用全局布尔位有点混乱.如果可以的话,返回方法已完成的想法似乎要好得多 工作正常!
公共局部类MainWindow:窗口 { 委托void taskDelegate(); 公共MainWindow() { InitializeComponent(); } 私人无效mybtn_Click(对象发送者,RoutedEventArgs e) { taskDelegate td1 =新的taskDelegate(this.AnotherMethod); IAsyncResult结果= td1.BeginInvoke(null,null); while(!result.IsCompleted) { myLabel.Content = myLabel.Content +."; Thread.Sleep(300); } td1.EndInvoke(result); } 私人void AnotherMethod() { Thread.Sleep(3000); } }
< Window x:Class =" WpfApplication1TestThreads.MainWindow" xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml" 标题="MainWindow".高度="350".宽度="525". <网格> < StackPanel> <标签名称="myLabel"; Content =线程"</Label> <按钮名称="mybtn";内容=按钮".点击=" mybtn_Click"</Button> </StackPanel> </Grid> </Window>
因此,解决方案的问题是您正在通过"Thread.Sleep"调用来阻止UI线程
这是使用4.5`await`功能的一种解决方案:
如果那不是一个选择,我建议使用计时器".
hi,
I am trying to determine the best way to display some moving text like "processing.. " "processing....." etc, ( the dots will get longer while another job is running. )
I would like to invoke this.AnotherMethod, let it start and while it is taking 4 seconds, i would like the while loop in mybtn_Click to update the label value. Then when the 4 seconds is complete, endinvoke sets result.IsCompleted and the loop stops.
Is this code anyway close to what I need? Any help would be very much appreciated. I have done it using global bool values but I find this using global bools abit messy. The idea of the method returning that it is completed seems far better if i could get it working!!!
public partial class MainWindow : Window { delegate void taskDelegate(); public MainWindow() { InitializeComponent(); } private void mybtn_Click(object sender, RoutedEventArgs e) { taskDelegate td1 = new taskDelegate(this.AnotherMethod); IAsyncResult result = td1.BeginInvoke(null, null); while (!result.IsCompleted) { myLabel.Content = myLabel.Content + "."; Thread.Sleep(300); } td1.EndInvoke(result); } private void AnotherMethod() { Thread.Sleep(3000); } }
<Window x:Class="WpfApplication1TestThreads.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid> <StackPanel> <Label Name="myLabel" Content="threads"></Label> <Button Name="mybtn" Content="button" Click="mybtn_Click"></Button> </StackPanel> </Grid> </Window>
So the problem with your solution is that you're blocking the UI thread with the `Thread.Sleep` calls.
Here's one solution using the 4.5 `await` functionality:
private async void Button_Click_1(object sender, RoutedEventArgs e) { Task longRunningOperation = Task.Run(() => DoLotsOfStuff()); string labelText = "Loading"; while (!longRunningOperation.IsCompleted) { for (int i = 1; i <= 5 && longRunningOperation.IsCompleted; i++) { myLabel.Content = labelText + new string('.', i); await Task.Delay(300); } } }If that's not an option I'd suggest using a `Timer`.
private void Button_Click_1(object sender, RoutedEventArgs e) { DispatcherTimer timer = new DispatcherTimer(); timer.Interval = TimeSpan.FromMilliseconds(300); string labelText = "Loading"; int numDecimals = 0; timer.Tick += (_, args) => { myLabel.Content = labelText + new string('.', numDecimals + 1); numDecimals = (numDecimals + 1) % 5; }; timer.Start(); Task longRunningOperation = Task.Task.Factory.StartNew(() => DoLotsOfStuff()) .ContinueWith(t => timer.Stop(), TaskScheduler.FromCurrentSynchronizationContext()); }
这篇关于异步方法并返回IAsyncResult的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!