到目前为止,我可以创建一个委托类型,例如:
// Can't use Task in WinRT interface and TypedEventHandler doesn't work with async await
public delegate IAsyncOperation<string> AsyncEventHandler(object sender, object args);
然后在WinRT对象中公开,如下所示:
public AsyncEventHandler OnMyEvent { get; set; }
在WinRT对象中,我会这样称呼它:
if (OnMyEvent != null)
{
var result = await OnMyEvent.Invoke(this, someArgs);
// Do something with the result...
}
使用WinRT对象的客户端代码可以做到这一点:
instanceOfWinRTObject.OnMyEvent = OnCalledBackFromWinRT;
但是由于委托人返回了IAsyncOperation
,因此我们需要进行一些包装:
private async Task<string> OnCalledBackFromWinRTAsync(object sender,
object args)
{
return await GetSomeStringAsync(args);
}
private IAsyncOperation<string> OnCalledBackFromWinRT(object sender, object args)
{
return OnCalledBackFromWinRTAsync(sender, args).AsAsyncOperation();
}
感觉好像必须有一种更清洁的方法来实现这一目标。
答案 0 :(得分:0)
这是彼得·托尔(Peter Torr)的评论提示的另一种选择。
public SCardError ListReaders(IntPtr hContext, string[] groups, out string[] readers) {
var dwReaders = 0;
// initialize groups array
byte[] mszGroups = null;
if (groups != null)
mszGroups = SCardHelper.ConvertToByteArray(groups, TextEncoding);
// determine the needed buffer size
var rc = SCardHelper.ToSCardError(
SCardListReaders(hContext,
mszGroups,
null,
ref dwReaders));
if (rc != SCardError.Success) {
readers = null;
return rc;
}
//doubling buffer size to work through thin clients
dwReaders *= 2; // <------------------ New line
// initialize array
var mszReaders = new byte[dwReaders * sizeof(char)];
rc = SCardHelper.ToSCardError(
SCardListReaders(hContext,
mszGroups,
mszReaders,
ref dwReaders));
readers = (rc == SCardError.Success)
? SCardHelper.ConvertToStringArray(mszReaders, TextEncoding)
: null;
return rc;
}
然后在WinRT组件中,您可以像这样调用事件:
// Custom event args class
public sealed class MyEventArgs
{
public string Result;
public Deferral Deferral;
}
// Declare the event handler on the WinRT component
public event TypedEventHandler<object, MyEventArgs> OnSuspendingEvent;
最后在客户端代码中添加如下处理程序:
if (OnSuspendingEvent != null)
{
var tcs = new TaskCompletionSource();
using (var deferral = new Deferral(() => tcs.SetResult(true)))
{
var myArgs = MyEventArgs();
myArgs.Deferral = deferral;
OnSuspendUnloading.Invoke(this, myArgs);
await tcs.Task;
DoSomethingWithResult(args.Result);
}
}