Home > Software engineering >  I'm not able to use "await" unless it's not in an lambda function
I'm not able to use "await" unless it's not in an lambda function

Time:10-16

I've been trying to make a function run asynchronously to prevent the window from freezing everytime it pings a new address but when I tried to implement it, VS said that I can't use the await operator as it's current state. Any suggestions?

        {
            //var reader = new Mp3FileReader(@"Resources\Audio\02 Connecting.flac");
            MediaFoundationReader sound = new MediaFoundationReader(@"Resources\Audio\Connecting.mp3");
            var waveOut = new WaveOut(); // or WaveOutEvent()
            waveOut.Init(sound);
            waveOut.Play();

            InitializeComponent();
            ContentRendered  = (s, e) => { await Connecting(); };
        }

       private async Task Connecting()
        {
            AutoResetEvent waiter = new AutoResetEvent(false);
            IPAddress ip = IPAddress.Parse("23.185.0.1");
            var pingSender = new Ping();

            pingSender.PingCompleted  = PingCompletedCallback;
            pingSender.SendAsync(ip, 1000, waiter);
        }```

CodePudding user response:

The issue is that you're trying to use await in a synchronous delegate:

ContentRendered  = (s, e) => { await Connecting(); };

To use the await keyword, you'll need an asynchronous delegate defined, to then add it to the event.

This should work - note the async keyword which enables the use of the await keyword:

ContentRendered  = async (s, e) => { await Connecting(); };

You should also await the asynchronous pingSender.SendAsync method:

await pingSender.SendAsync(ip, 1000, waiter);

CodePudding user response:

Unless you are using the Connecting asynchronous method in more than one places, it is probably preferable from a maintainability point of view to attach a classic event handler to the ContentRendered event:

ContentRendered  = ContentRenderedHandler;

//...

private async void ContentRenderedHandler(object sender, EventArgs e)
{
    AutoResetEvent waiter = new AutoResetEvent(false);
    //...
    await pingSender.SendAsync(ip, 1000, waiter);
}

This is essentially the same with what Ermiya Eskandary suggests in their answer, with the only difference being that the presence on an async void method is visible and explicit. The use of async void here is correct, because the method is an event handler. It's a good idea to be explicit though, because async void methods are too often misused, resulting in unexpected behavior, or compiler warnings, or both.

  • Related