gpt4 book ai didi

c# - 我可以摆脱这个可怕的阻止代码吗?

转载 作者:行者123 更新时间:2023-12-03 13:20:01 24 4
gpt4 key购买 nike

我需要一些帮助,在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线程上进行阻止吗?当然,每个请求都不会在自己的线程上处理吗?

有什么方法可以使这段代码更整洁,最重要的是更有效吗?

最佳答案

回答问题:

In a web api service call, I need to call a function in a dll that executes asynchronously, and then gives the response in a call back function.



IMO,执行此操作的最佳方法是使您的 Controller 方法异步,并使用 TaskCompletionSource包装DLL的回调。一些不错的附加读物:
  • Using Asynchronous Methods in ASP.NET MVC 4
  • The Nature of 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;
    }

    // ...
    }

    关于c# - 我可以摆脱这个可怕的阻止代码吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22342967/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com