C# 使异步API同步

C# 使异步API同步,c#,asynchronous,C#,Asynchronous,我正在连接一个API以获取一些定义如下的数据: // defined in the API dll public class ClientConnection { public ClientConnection(IApi api) { ... } public void request(int reqid, string reqdetails) { ... } } interface IApi { void receiveData(int reqid, string a

我正在连接一个API以获取一些定义如下的数据:

// defined in the API dll
public class ClientConnection {
    public ClientConnection(IApi api) { ... }
    public void request(int reqid, string reqdetails) { ... }
}

interface IApi
{
    void receiveData(int reqid, string ans);
}
客户端对象
ClientConnection
,允许发送请求。 需要传递到
ClientConnection
以接收回调的IApi接口。 示意图如下所示:

// defined in the API dll
public class ClientConnection {
    public ClientConnection(IApi api) { ... }
    public void request(int reqid, string reqdetails) { ... }
}

interface IApi
{
    void receiveData(int reqid, string ans);
}
现在,显然这是一种相当标准的异步方式:通过带有requestid的全局对象发送请求,然后接收带有requestid标记的答案

我想创建一个同步的包装器。这样做最自然的方式是什么?是否有一种使用async await而不是使用线程锁定之类的智能方法

class MyWrapper : IApi
{
    private ClientConnection _client;
    private int _reqToken = 0;
    public MyWrapper()
    {
        _client = new ClientConnection(this);
    }

    public string getData(string reqdetails)
    {
        _client.request(_reqToken++, reqdetails);
        // what to do here?
    }

    public void receiveData(int reqid, string data) {
        // what to do here?
    }
}

虽然没有测试下面的代码,但它应该会让您产生想法。基本上,您可以使用
ManualResetEvent
在收到结果时发出信号(在没有适当超时的情况下,永远不要调用此命令):

类MyWrapper:IApi{
私人客户端连接(ClientConnection);;
//在这里存储您的请求
私有字典_pendingRequests=新字典();
专用int_reqToken=0;
公共MyWrapper(){
_客户端=新客户端连接(此);
}
公共字符串getData(字符串请求详细信息、时间跨度超时){
//如果这是多线程-在添加\删除请求时锁定_pendingRequests
//当您增加您的_reqToken或使用并发集合时
使用(var token=new PendingRequest()){
变量id=_reqToken;
//锁在这里
_添加(id,令牌);
_客户请求(id、需求详情);
//这里使用联锁。增量
_reqToken++;
if(!token.Signal.WaitOne(timout)){
//这里呢
_pendingRequests.Remove(id);
//超时
抛出新异常(“timout”);
}
//如果我们在这里-我们有结果
返回token.Result;
}
}
公共无效接收数据(输入请求ID、字符串数据){
//在这里,您可能也需要锁定
如果(_pendingRequests.ContainsKey(reqid)){
var令牌=_pendingRequests[reqid];
_pendingRequests.Remove(请求ID);
令牌。完成(数据);
}
}
私有类挂起请求:IDisposable{
公共挂起请求(){
信号=新手动复位事件(假);
}
公共手动重置事件信号{get;private set;}
公共字符串结果{get;private set;}
公共作废完成(字符串结果){
结果=结果;
Signal.Set();
}
公共空间处置(){
Signal.Dispose();
}
}
}
不客气:)如果它不起作用或包含一些错误,请告诉我,以便我可以修复答案