[英]Dealing with a callback that must populate a field in another class's instance
I have a class SomeAction
which implements ISomeAction
(given to me), it has an async method that calls a non async void method which belongs to a class instance that is provided by a third party sdk. 我有一个实现
ISomeAction
的类SomeAction
(给我),它有一个异步方法,该方法调用一个非异步void方法,该方法属于第三方sdk提供的类实例。 To handle the void
in my async method, I use TaskCompletionSource
which I intend on setting once I get the response from the third party. 为了处理异步方法中的
void
,我使用TaskCompletionSource
,一旦收到第三方的响应,便打算进行设置。 The problem is, the response from the service is in the form of a callback which uses a class ThirdPartyCallbackClass
that the third party has a defined interface for. 问题是,来自服务的响应采用了回调的形式,该回调使用了第三方为其定义接口的
ThirdPartyCallbackClass
类。
So how can I take the string
passed back to the ThirdPartyCallbackClass
and use it to update the TaskCompletionSource
instance in SomeAction
所以,我怎么可以把
string
传递回ThirdPartyCallbackClass
,并用它来更新TaskCompletionSource
的情况下SomeAction
Here is the code (forgive any typos): 这是代码(可避免任何拼写错误):
public class SomeAction : ISomeAction
{
private TaskCompletionSource<string> fbtcs;
public async Task<string> someTask()
{
var accessToken = await SomeAsyncMethod();
return accessToken;
}
private async Task<string> SomeAsyncMethod()
{
fbtcs = new TaskCompletionSource<string>();
TaskClass tc = new TaskClass();
tc.CallThirdParty();
return await fbtcs.Task;
}
}
public class TaskClass
{
public void CallThirdParty()
{
ThirdParty tp = new ThirdParty();
var somePayload = "payload";
ThirdPartyCallbackClass callback = new ThirdPartyCallbackClass();
tp.VoidMethodWithCallback(somePayload, callback);
}
}
public class ThirdPartyCallbackClass : IThirdPartyDefinedCallback
{
public void OnSuccess(string p)
{
//At this point I want to take p and use it to update SomeAction's fbtcs instance string. Is my design wrong or is there a strategy for dealing with this?
//If this was in my `SomeAction` instance I would try to do something like...
//fbtcs.TrySetResult(p);
}
}
If ThirdParty::VoidMethodWithCallback
is a synchronous method then you don't need to use TaskCompletionSource
at all, you can call synchronous methods directly in an async
or Task<TResult>
-returning method: 如果
ThirdParty::VoidMethodWithCallback
是同步方法,则根本不需要使用TaskCompletionSource
,可以直接在async
或Task<TResult>
返回方法中直接调用同步方法:
public class SomeAction : ISomeAction
{
public Task<String> SomeTaskAsync()
{
return Task.FromResult( this.SomeMethod() );
}
private String SomeMethod()
{
String value = new TaskClass().CallThirdParty();
return value;
}
}
public class TaskClass
{
private class CallbackContainer : IThirdPartyDefinedCallback
{
public String ReturnedValue;
public void OnSuccess(String p)
{
this.ReturnedValue = p;
}
}
public String CallThirdParty()
{
ThirdParty tp = new ThirdParty();
var somePayload = "payload";
CallbackContainer callbackContainer = new CallbackContainer();
tp.VoidMethodWithCallback( somePayload, callbackContainer );
return callbackContainer.ReturnedValue;
}
}
In the event that SomeTaskAsync
is called directly from a UI thread or some other thread that should not block, then use Task.Run
to run the synchronous method on a Thread-pool thread: 如果直接从UI线程或不应阻塞的其他线程中直接调用
SomeTaskAsync
,请使用Task.Run
在线程池线程上运行同步方法:
public class SomeAction : ISomeAction
{
public Task<String> SomeTaskAsync()
{
return Task.Run( (Func<String>)this.SomeMethod );
}
}
Note the standard (ie Microsoft) naming convention in .NET is to always have Async
at the end of the name of any method which ultimately executes asynchronously (it doesn't necessarily need to be flagged with the async
modifier: it could pass-through a Task<T>
from another call, for example). 请注意,.NET中的标准(即Microsoft)命名约定始终是在最终最终异步执行的任何方法名称的末尾都带有
Async
(它不一定需要用async
修饰符标记:它可以通过例如,另一个调用中的Task<T>
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.