我的WebApi中的事件处理程序

时间:2016-11-10 16:29:37

标签: c# asp.net asp.net-web-api asp.net-web-api2

目前我必须连接到plc-terminal(基于tcp /套接字)。好的部分是制造商提供了一个dll,它为我提取所有这些功能。糟糕的部分,一切都是用事件处理程序编程的。 这个

的简化示例
public void GetOutputs(string id)
{    
    ConfigurationManager cm = new ConfigurationManager();
    cm.GetOutputResult += OnGetOutputResult;    
    cm.GetOutputAsync(id);
}

private void OnGetOutputResult(Output output)
{
    //do something here with the output when not null
}

我想创建一个WebApi项目,这样所有的客户端(UWP,Xamarin,ASP MVC)都可以通过http访问这个终端,所以不会有使用Portable或.NET Core库的大惊小怪。无法从制造商那里引用完整的.NET Framework dll。

所以我的问题是:甚至可以在WebApi中做这些事情吗?有没有办法将这些回调很好地转换为等待的任务?

public class OutputsController : ApiController
{
    public IHttpActionResult Get(string id)
    {
        ConfigurationManager cm = new ConfigurationManager();
        //task/async/await magic here
        return Ok(output); // or NotFound();
    }

此致 Miscode

1 个答案:

答案 0 :(得分:1)

您可以使用专为此类情景设计的TaskCompletionSource

private TaskCompletionSource<Output> tcs;

public Task<Output> GetOutputs(string id)
{    
    tcs = new TaskCompletionSource<Output>();

    ConfigurationManager cm = new ConfigurationManager();
    cm.GetOutputResult += OnGetOutputResult;    
    cm.GetOutputAsync(id);

    // this will be the task that will complete once tcs.SetResult or similar has been called
    return tcs.Task;
}

private void OnGetOutputResult(Output output)
{
    if (tcs == null) {
        throw new FatalException("TaskCompletionSource wasn't instantiated before it was called");
    }

    // tcs calls here will signal back to the task that something has happened.
    if (output == null) {
       // demoing some functionality
       // we can set exceptions
       tcs.SetException(new NullReferenceException());
       return;
    }

    // or if we're happy with the result we can send if back and finish the task
    tcs.SetResult(output);
}

在你的api中:

public class OutputsController : ApiController
{
    public async Task<IHttpActionResult> Get(string id)
    {
        ConfigurationManager cm = new ConfigurationManager();

        var output = await cm.GetOuputs(id);

        return Ok(output); // or NotFound();
    }