我可以摆脱这种可怕的阻塞代码?(Can I get rid of this horrible blo

2019-10-19 13:33发布

我需要一些帮助,在Web API服务电话,我需要调用一个函数在执行异步,然后给出了一个回调函数的响应的DLL。 现在通常这将是一件好事,但现在的web API的想法是要执行的命令,然后返回响应。

下面是我这工作当前的代码,但我认为它可怕的代码,它的一切你不想做的事。 特别是当这个代码是要为每个请求运行一个Web服务器上。

[HttpGet]
    public HttpResponseMessage Off(string id)
    {
        APNLink.Link link = LinkProvider.getDeviceLink(id, User.Identity.Name);

        if (link.LinkConnectionStatus == APNLink.ConnectionStatus.Connected)
        {
            link.RelayCommand(APNLink.RelayNumber.Relay1, APNLink.RelayCommand.OFF, test);
            BlockForResponse();
            var msg = Request.CreateResponse(HttpStatusCode.OK);
            return msg;
        }
        else
        {
            if (link.Connect())
            {
                var status = link.LinkConnectionStatus;
                int timeout = 0;
                while (status != APNLink.ConnectionStatus.Connected)
                {
                    Thread.Sleep(500);
                    status = link.LinkConnectionStatus;
                    if (status == APNLink.ConnectionStatus.Connected)
                    {
                        break;
                    }                        
                    if (timeout++ > 16)
                    {
                        var msg1 = Request.CreateResponse(HttpStatusCode.RequestTimeout);
                        return msg1;
                    }
                }
                link.RelayCommand(APNLink.RelayNumber.Relay1, APNLink.RelayCommand.OFF, test);
                BlockForResponse();
                var msg = Request.CreateResponse(HttpStatusCode.OK);
                return msg;
            }
            else
            {
                var msg2 = Request.CreateResponse(HttpStatusCode.BadRequest);
                return msg2;
            }
        }

    }

    bool flag = false;

    public void test(bool var)
    {
    flag = true;
    }

     private static bool BlockForResponse()
    {
        int count = 0;
        while (!flag)
        {
            Thread.Sleep(500);
            if (count > 10)
            {
                //timeout
                return false;
            }
        }
        return true;
    }

现在的是我必须阻止等待DLL时,连接到被连接,只有我可以执行的命令。 一旦我执行的命令。 然后,我不得不再次为响应块。

另一个方面是,我可以在一个asp.net线程实际阻止? 当然每个请求都不会在自己的线程处理?

有没有什么办法可以使此代码整洁,最重要的更有效率?

Answer 1:

回答这个问题:

在Web API服务电话,我需要调用一个函数在执行异步,然后给出了一个回调函数的响应的DLL。

IMO,这样做的最好的办法是让你的控制器的方法异步和使用TaskCompletionSource来包装你的DLL的回调。 有一些很好的额外内容如下:

  • 使用ASP.NET MVC 4异步方法 。
  • 的性质TaskCompletionSource<TResult>

该代码可能是这个样子:

[HttpGet]
public async Task<HttpResponseMessage> Off(string id)
{
    APNLink.Link link = LinkProvider.getDeviceLink(id, User.Identity.Name);

    if (link.LinkConnectionStatus == APNLink.ConnectionStatus.Connected)
    {
        var tcs = new TaskCompletionSource<object>();

        CallbackType test = delegate {           
           tcs.SetResult(null);
        };

        link.RelayCommand(
            APNLink.RelayNumber.Relay1, 
            APNLink.RelayCommand.OFF,
            test);

        // BlockForResponse();
        await tcs.Task; // non-blocking

        var msg = Request.CreateResponse(HttpStatusCode.OK);
        return msg;
    }

    // ...
}


文章来源: Can I get rid of this horrible blocking code?