我需要一些帮助,在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线程吗?当然,每个请求都不会在自己的线程上处理?
有什么方法可以让这个代码更整洁,最重要的是更有效率?
答案 0 :(得分:3)
回答这个问题:
在web api服务调用中,我需要在dll中调用一个函数 异步执行,然后在回调中给出响应 功能
IMO,这样做的最佳方法是使控制器方法异步,并使用TaskCompletionSource
来包装DLL的回调。一些好的附加读物:
代码可能如下所示:
[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;
}
// ...
}