异步方法并返回IAsyncResult [英] Async Methds and returning IAsyncResult

查看:71
本文介绍了异步方法并返回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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆