Home>

In the following source code
I want to get the value bar generated in the method Hogehoge by the process in Btn_Click at any time.
I created the method GetValueAsync
The while loop in GetValueAsync causes very high CPU usage.

Corresponding source code
private string _foo;
private async task Hogehoge ()
{
    while (conditional expression)
    {
        ...
        this._foo = bar;// bar is the value generated in this Hogehoge
    }
    ...
}
private async Task<string>GetValueAsync ()
{
    var value = await Task.Run (() =>
    {
        while (true)
        {
            if (this._foo! = null)
                return this ._foo;
        }
    });
    this._foo = null;
    return value;
}
public async void Btn_Click (object sender, RoutedEventArgs e)
{
    while (true)
    {
        Debug.WriteLine (await GetValueAsync ());
    }
}
What I tried

As shown below, when Task.Delay (1) is inserted, the CPU usage rate does not increase, but
I'm wondering if such a solution is okay (why this is the solution in the first place), and if there is another better way.

If i am familiar with it, please teach it.

private async Task<string>GetValueAsync ()
{
    var value = await Task.Run (async () =>
    {
        while (true)
        {
            await Task.Delay (1);// Add this
            if (this._foo! = null)
                return this ._foo;
        }
    });
    this._foo = null;
    return value;
}
Supplement (what I want to achieve)

Regarding getting the value of bar
It's fine if you can get the value of bar at the timing when GetValueAsync is called in Btn_Click.
I want to get the value of the bar when GetValueAsync is called in Btn_Click (however, if the bar has not been updated, wait until it is updated).

solution?

Based on the answers you received, I tried to improve the code.

private readonly AutoResetEvent condition = new AutoResetEvent (false);
private async Task<string>GetValueAsync ()
{
    await Task.Run (() =>
    {
        condition.WaitOne ();
    });
    return this._originaltext;
}


In the Hogehoge method,
this._foo = bar;under,condition.Set ();Describe.

  • Answer # 1

    Don't wait in a while loop,
    Use synchronous events such as AutoResetEvent

    AutoResetEvent Class (System.Threading) | Microsoft Docs

  • Answer # 2

    I created a method GetValueAsync to get the value bar generated in the method Hogehoge at any time by the process in Btn_Click.

    I think private string _foo;and private async task Hogehoge () belong to some class, so why not add a property to that class that returns the value of _foo and get it via it? ??

    The code looks like this: (Variables, method names, etc. are changed from the question code)

    using System;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    namespace WindowsFormsAsyncTest
    {
        public partial class Form6: Form
        {
            private MyClass myClass;
            public Form 6 ()
            {
                InitializeComponent ();
            }
            private async void button1_Click (object sender, EventArgs e)
            {
                this.myClass = new MyClass ();
                await this.myClass.MyAsyncMethod ();
            }
            private void button2_Click (object sender, EventArgs e)
            {
                if (this.myClass! = null)
                {
                    this.label1.Text = this.myClass.Value;
                }
            }
        }
        public class MyClass
        {
            private string _value;
            public string Value
            {
                get {return _value;}
            }
            public async Task MyAsyncMethod ()
            {
                // Up to 100 for the time being
                int i = 0;
                while (i<100)
                {
                    // Some action and bar generation
                    // Substitute Task.Delay (100) and i
                    await Task.Delay (100);
                    string bar = "Bar value:" + i;
                    this._value = bar;
                    i ++;
                }
            }
        }
    }

    The results are as follows.

    ]