我可以摆脱这个可怕的阻止代码吗? [英] Can I get rid of this horrible blocking code?
问题描述
我需要一些帮助,在Web api服务调用中,我需要在dll中调用一个异步执行的函数,然后在回调函数中给出响应.现在通常这会很好,但是现在有了Web api,其想法是执行命令,然后返回响应.
I need some help, 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. Now normally this would be good , but now with a web api the idea is to execute the command and then return the response.
下面是我当前可以使用的代码,但是我认为它的代码很糟糕,它是您不想执行的所有操作.尤其是在Web服务器上,对于每个请求都将运行此代码时.
Below is my current code which works, but I think its terrible code, its everything you don't want to do. Especially on a web server when this code is going to run for every request.
[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,连接连接时必须阻塞,然后才可以执行命令.一旦我执行了命令.然后,我必须再次阻止以获取响应.
now the thing is I have to block when waiting for the dll, Connection to be connected, only then can I execute the command. once I have executed the command. I then have to block again for the response.
另一方面是,我可以实际阻止asp.net线程吗?当然每个请求都不会在自己的线程上处理吗?
Another aspect is, Can I actually block on an asp.net thread? Surely each request is not handled on its own thread?
有什么方法可以使这段代码更整洁,最重要的是更有效吗?
Is there any way I can make this code neater and most importantly more efficient?
推荐答案
回答问题:
在Web api服务调用中,我需要在dll中调用一个函数 异步执行,然后在回调中给出响应 功能.
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,执行此操作的最佳方法是使控制器方法异步并使用TaskCompletionSource
包装DLL的回调.一些不错的附加读物:
IMO, the best way of doing this is to make your controller method asynchronous and use TaskCompletionSource
to wrap the callback of your DLL. Some good additional reads:
- Using Asynchronous Methods in ASP.NET MVC 4.
- The Nature of
TaskCompletionSource<TResult>
.
代码可能看起来像这样:
The code may look something like this:
[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;
}
// ...
}
这篇关于我可以摆脱这个可怕的阻止代码吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!