简体   繁体   中英

How to use Async Task in sync method

I have a Async Task which returns string after certain delay. I have use Async task in a method, inorder to get appended string as output.

I have used a Button and Label. I have used Button Click event to load the text for the label named 'text'.

I don't want to use delay in button click.

private void Load_Click(object sender, RoutedEventArgs e)
{
    text.Text = "";
    TextAsync();        
    text.Text = text.Text + newValue;
    text.Text =text.Text+ "Ashokkumar Viswanathan";
}

internal async Task<string> LoadText()
{
    await Task.Delay(20000);
    newValue = "Async Value";
    return newValue;
}

private async void TextAsync()
{
    await LoadText();
}

Expected Output: text.Text="Async Value Ashokkumar Viswanathan

actual output: text.Text="Ashokkumar Viswanathan"

How to use Async Task in sync method

I think you're seeing a good amount of confusion over your question because you're trying to do something that's wrong. You actually want to block the UI thread, which gives your customers a worse user experience. Also, this is a UWP app, so note that blocking the UI will result in a rejection from the app store, if that is your means of distribution.

If the actual problem you're trying to solve is something like "don't let the user click the button again until its operation completes", then the proper solution would match that, eg, disabling the button until the operation completes.

But, assuming you really want to block the UI thread and give your users a worse experience with your software, you can use one of the hacks described in this article . None of these hacks work in every situation, so it's impossible for us to know whether they will work for you, but in your case, I'd guess the thread pool hack will allow you to block the UI thread without a deadlock:

private void Load_Click(object sender, RoutedEventArgs e)
{
  text.Text = "";
  Task.Run(() => LoadText()).GetAwaiter().GetResult();
  text.Text = text.Text + newValue;
  text.Text = text.Text+ "Ashokkumar Viswanathan";
}

As a final note, I must emphasize that I don't recommend this. I see no reason to purposefully degrade the user experience.

I don't want to make Button clicked event as async. I want to know, whether we can use async task in normal button click to get text.

Not using TextAsync since it doesn't return a Task (as it should) but if you call LoadText() directly, you can use the ContinueWith method:

private void Load_Click(object sender, RoutedEventArgs e)
{
    text.Text = "";
    LoadText().ContinueWith(t =>
    {
        text.Text = text.Text + newValue;
        text.Text = text.Text + "Ashokkumar Viswanathan";
    }, System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
}

I would still recommend you to define the event handler as async and await either TextAsync() or LoadText() though. This is the recommended approach:

private async void Load_Click(object sender, RoutedEventArgs e)
{
    text.Text = "";
    await LoadText();
    text.Text = text.Text + newValue;
    text.Text = text.Text + "Ashokkumar Viswanathan";
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM