我正在尝试为 Xamarin 的 Amazon IAP 插件实现包装器。它以下列方式使用基于事件的系统:
您可以发起方法调用并监听事件。方法调用发起请求,其中一些返回响应。事件是系统生成的异步消息,它们响应方法调用而发送,以将请求的数据返回给您。 在这里查看更多
我的目标是将这个基于事件的系统包装到一些 API 中,这样我就可以将插件与任务一起使用,这样我就可以使用async-await
语法。为了实现这一点,我TaskCompletionSource
在下面的例子中使用了类似的东西:
public async Task<bool> GetProductInfoAsync(params string[] productIds)
{
var iapService = AmazonIapV2Impl.Instance;
var tcs = new TaskCompletionSource<bool>();
var skus = new SkusInput { Skus = productIds.ToList() };
var requestId = iapService.GetProductData(skus).RequestId;
GetProductDataResponseDelegator delegator = null;
delegator = new GetProductDataResponseDelegator(response =>
{
if(response.Id == requestId) {
var result = GetResultFromResponse(response);
tcs.SetResult(result);
//iapService.RemoveGetProductDataResponseListener(delegator.responseDelegate);
}
});
iapService.AddGetProductDataResponseListener(delegator.responseDelegate);
return await tcs.Task;
}
如果该方法被调用一次,此代码似乎可以正常工作,但如果它被连续调用两次,则应用程序立即崩溃,并且打印到控制台的唯一内容是以下消息..
[mono] Unhandled Exception:
[mono] System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
[mono-rt] [ERROR] FATAL UNHANDLED EXCEPTION: System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
..这根本没有意义。
那么我在这里有什么明显的遗漏吗?或者它可能是插件的错误?
我已经使用上面的代码创建了一个存储库,因此您可以重现该问题。这是我的游乐场,所以请忽略项目的整个结构,只关注AmazonIAPService和MainActivity类。
提示 1:
注释行//iapService.RemoveGetProductDataResponseListener(delegator.responseDelegate);
也会导致崩溃,消息相同,但在第一次调用该方法时已经发生。
提示 2:
包含AmazonIAPService
一个注释方法,它await Task.Delay(TimeSpan.FromMilliseconds(1))
以一种我真的不喜欢的非常 hacky 的方式使用和解决上面的问题。