gpt4 book ai didi

c# - 试图让方法等待内部事件处理完成

转载 作者:太空狗 更新时间:2023-10-30 01:20:13 24 4
gpt4 key购买 nike

我是 C# async/await 的新手,在尝试使用异步方法时遇到了一些问题。我有一个收藏:

private IList<IContactInfo> _contactInfoList

还有一个异步方法:

public async Task<IList<IContactInfo>> SelectContacts()
{
_contactInfoList = new List<IContactInfo>();
ContactsSelector selector = new ContactsSelector();
selector.ShowPicker();

selector.ContactsSelected += (object sender, ContactsSelectorEventArgs e) =>
{
this._contactInfoList = e.Contacts;
};

return _contactInfoList;
}

联系人选择器是一个弹出式用户控件,它允许从手机中选择一些联系人,并且在点击“确定”按钮后它会触发 ContactsSelected 事件。我需要从事件参数 e.Contacts 中获取选定的联系人列表,并在上述 SelectContacts() 异步方法中返回该列表。这就是问题所在:在 ContactsSelected 事件完成其工作之前,我的方法已经返回空列表 _contactInfoList。我知道在这种情况下 async/await 甚至无关紧要,这个问题将存在于通常的方法中,但我只需要使该方法等待事件处理结果。

最佳答案

这里需要做的是将异步编程的事件风格转换为异步编程的任务风格。 TaskCompletionSource 的使用使这变得相当简单。

public static Task<IList<IContactInfo>> WhenContactsSelected(
this ContactsSelector selector)
{
var tcs = new TaskCompletionSource<IList<IContactInfo>>();
selector.ContactsSelected += (object sender, ContactsSelectorEventArgs e) =>
{
tcs.TrySetResult(e.Contacts);
};
return tcs.Task;
}

现在我们有了一个返回任务和我们需要的结果的方法,使用它的方法非常简单:

public Task<IList<IContactInfo>> SelectContacts()
{
ContactsSelector selector = new ContactsSelector();
selector.ShowPicker();

return selector.WhenContactsSelected();
}

这里有几点需要注意。首先,我删除了实例字段;这似乎是个坏主意。如果多次调用 SelectContacts,将导致两者争夺该字段。从逻辑上讲,如果您确实需要存储列表,它应该是一个局部变量。接下来,这里没有使用 await,因此该方法不应标记为 async。如果你想await调用WhenContactsSelected然后随意添加async回来,但到目前为止我认为没有真正需要它.

关于c# - 试图让方法等待内部事件处理完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19845829/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com