我无法使用"await",除非它不在 lambda 函数中

  • 本文关键字:lambda 函数 await c# asynchronous
  • 更新时间 :
  • 英文 :


我一直试图使一个函数异步运行,以防止窗口冻结每次它ping一个新的地址,但当我试图实现它,VS说,我不能使用等待操作符,因为它的当前状态。有什么建议吗?

public MainWindow()
{
//var reader = new Mp3FileReader(@"ResourcesAudio2 Connecting.flac");
MediaFoundationReader sound = new MediaFoundationReader(@"ResourcesAudioConnecting.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);
}

问题是您试图在同步委托中使用await:

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

要使用await关键字,您需要定义一个异步委托,然后将其添加到事件中。

这应该可以工作-注意async关键字允许使用await关键字:

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

你还应该等待异步pingSender.SendAsync方法:

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

除非您在多个地方使用Connecting异步方法,否则从可维护性的角度来看,将经典事件处理程序附加到ContentRendered事件可能是更好的:

ContentRendered += ContentRenderedHandler;
//...
private async void ContentRenderedHandler(object sender, EventArgs e)
{
IPAddress ip = IPAddress.Parse("23.185.0.1");
var pingSender = new Ping();
PingReply pingReply = await pingSender.SendPingAsync(ip, 1000);
// Use the `pingReply` here
}

这与Ermiya Eskandary在他们的回答中所建议的基本相同,唯一的区别是async void方法上的存在是可见的和显式的。这里使用async void是正确的,因为该方法是一个事件处理程序。尽管如此,显式是一个好主意,因为async void方法经常被滥用,导致意外行为,或编译器警告,或两者兼而有之。


更新:您的代码使用了过时的PingCompleted+SendAsync方法。Ping类提供了较新的SendPingAsyncAPI(。. NET Framework 4.5及更高版本),可以通过async-await直接使用。

相关内容

  • 没有找到相关文章

最新更新