[英]Can I get rid of this horrible blocking code?
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. 我需要一些帮助,在web api服务调用中,我需要在一个异步执行的dll中调用一个函数,然后在回调函数中给出响应。 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 api的想法是执行命令然后返回响应。
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. 特别是在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;
}
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. 然后,我必须再次阻止响应。
Another aspect is, Can I actually block on an asp.net thread? 另一个方面是,我可以实际阻止asp.net线程吗? 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? 有什么方法可以让这个代码更整洁,最重要的是更有效率?
Answering the question: 回答这个问题:
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. 在web api服务调用中,我需要调用异步执行的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. IMO,这样做的最好方法是使您的控制器方法异步,并使用TaskCompletionSource
来包装DLL的回调。 Some good additional reads: 一些好的附加读物:
TaskCompletionSource<TResult>
. TaskCompletionSource<TResult>
的性质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;
}
// ...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.