简体   繁体   中英

Async Await Stops... C# WPF

I have a function that gets a Func as a parameter and executes it inside of a task in a async method in order to display indeterminate progress bar while the function is working....

private async void Invoke(Func<string> function)
{
       if(calculation?.Status == TaskStatus.Running) await calculation;
       calculation = Task.Run(function);
       InvokeA(() => prg.Height = double.NaN);
       InvokeA(() => prg.Visibility = Visibility.Visible);
       Result = await calculation;
       InvokeA(() => prg.Visibility = Visibility.Hidden);
       InvokeA(() => prg.Height = 0);
}

The problem is when ever the function reaches the:

Result = await Calculation;

it sort of stops... it never gets to actually setting the value or closing the progress bar.

Invoke Is Called from a Textbox.KeyDown Method if the key is Enter:

if (SpecialCommands.DoesExist(Text))
    {
          Invoke(() => SpecialCommands.Invoke(Parameter));
          if (!string.IsNullOrEmpty(Result)) Text += $"   --->   {Result}";
     }

variables definition:

calculation = Task<string>
Result = string
prg = ProgressBar
Parameter = string that isn't connected to the UI

I've created a standard new WPF application project with the following XAML

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication1"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Canvas>
        <Button x:Name="button" Content="Button" Canvas.Left="62" Canvas.Top="40" Width="75" Click="button_Click"/>
        <ProgressBar x:Name="prg" Height="23" Canvas.Left="62" Canvas.Top="265" Width="347" IsIndeterminate="True"/>
    </Canvas>
</Window>

and code behind

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    Task<string> calculation;
    string Result;
    string Text;

    private async void button_Click(object sender, RoutedEventArgs e)
    {
        await Invoke(() => Foo());
        if (!string.IsNullOrEmpty(Result)) Text += $"   --->   {Result}";
    }

    private async Task Invoke(Func<string> function)
    {
        if (calculation?.Status == TaskStatus.Running) await calculation;
        calculation = Task.Run(function);
        InvokeA(() => prg.Height = double.NaN);
        InvokeA(() => prg.Visibility = Visibility.Visible);
        Result = await calculation;
        InvokeA(() => prg.Visibility = Visibility.Hidden);
        InvokeA(() => prg.Height = 0);
    }

    private void InvokeA(Action a) { a(); }

    static string Foo()
    {
        Thread.Sleep(5000);
        return "Bar";
    }
}

and it's working as expected. So the problem is somewhere else from what you provided.

EDIT Based on your comment, it's worth trying the following, because that was the incorrect part of your code:

First, change the signature of the Invoke method to be

private async Task Invoke(Func<string> function)

and then use

await Invoke(() => Foo());
if (!string.IsNullOrEmpty(Result)) Text += $"   --->   {Result}";

Hope that helps.

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