ASP.NET Web服务方法有没有办法使用异步方法?

时间:2022-04-12 13:51:25

I have an ASP.NET webservice (.asmx) with a simple method that reads something from the DB with a sync call (ExecuteReader) and returns the result. There is any way to optimize the Thread Pool usage (ie. by calling an async call (BeginExecuteReader)) without changing the method's signature?

我有一个ASP.NET webservice(.asmx),它有一个简单的方法,通过同步调用(ExecuteReader)从DB读取内容并返回结果。有没有办法优化线程池的使用(即通过调用异步调用(BeginExecuteReader))而不更改方法的签名?

The intention is to not block a thread pool thread while the database operation is in progress; it is not the intention to speed things up by doing multiple operations in parallel.

目的是在数据库操作进行时不阻塞线程池线程;并不打算通过并行执行多个操作来加快速度。

4 个解决方案

#1


Actually, the answer is yes. See Asynchronous XML Web Service Methods.

实际上,答案是肯定的。请参阅异步XML Web服务方法。

Although you create an async web method with Begin* and End* methods, .NET will only create a single operation in the WSDL. This is obvious if you think about it - what would a Java client do with an IAsyncResult?

虽然使用Begin *和End *方法创建异步Web方法,但.NET只会在WSDL中创建单个操作。如果你考虑一下这很明显 - Java客户端对IAsyncResult会做什么?

The client can call the operation synchronously or asynchronously.

客户端可以同步或异步调用操作。

#2


With the specific use-case that you provide, with a single async call, it would not be worth it, but, yes, you can invoke async calls from a web service:

使用您提供的特定用例,通过单个异步调用,它是不值得的,但是,是的,您可以从Web服务调用异步调用:

[WebMethod]
public SomeResult SynchronousMethod() {
    IAsyncResult someWork = BeginSomeAsyncWork();
    IAsyncResult otherWork = BeginOtherAsyncWork();
    WaitHandle[] all = new WaitHandle[] { someWork.AsyncWaitHandle, otherWork.AsyncWaitHandle };
    // TODO: Do some synchronous work here, if you need to 
    WaitHandle.WaitAll(all); /* this is the important part, it waits for all of the async work to be complete */
   var someWorkResult = EndSomeAsyncWork(someWork);
   var otherWorkResult = EndSomeAsyncWork(otherWork);
   // TODO: Process the results from the async work
   // TODO: Return data to the client
}

The important thing here is the WaitHandle.WaitAll, which will block until all of the async work is complete. If you can process the results individually, you could use WaitHandle.WaitAny instead, but the code gets more complicated, and is a bit out of the scope of the question.

这里重要的是WaitHandle.WaitAll,它将阻塞直到所有异步工作完成。如果您可以单独处理结果,则可以使用WaitHandle.WaitAny,但代码变得更复杂,并且有点超出了问题的范围。

#3


Yes, you're basically free to do what you want in responding to Service request. But if you only have 1 query it's not going to be of much use. If you need 2 queries or more it becomes interesting.

是的,你基本上可以*地做你想要的服务请求。但是如果你只有1个查询,它就不会有多大用处。如果您需要2个或更多查询,那就变得有趣了。


And then ofcourse you have to collect all results, as Alex Lyman points out. The ASP.NET WebPage has special support for this, that's why I'm sure it is possible.

然后当然,你必须收集所有结果,正如Alex Lyman指出的那样。 ASP.NET WebPage对此有特殊支持,这就是为什么我确信它是可行的。

#4


I don't see how this would work, when a request comes in for your webservice, a thread from the pool is going to be allocated to process the request, if you make an async call from that thread then your request thread ends and the client would not get any result back.

我没有看到这是如何工作的,当你的web服务请求进入时,来自池的线程将被分配来处理请求,如果你从该线程进行异步调用,那么你的请求线程结束并且客户不会得到任何结果。

Short Answer is No. People only seem to be reading this line and downvoting :) The user is asking if we can do an async call from inside a sync webservice call, which is certainly possible by using WaitHandles but does not make sense in the user's specific case.

简短的答案是否定的。人们似乎只是在阅读这一行并且正在低估:)用户问我们是否可以从同步webservice调用内部执行异步调用,这当然可以通过使用WaitHandles来实现,但在用户的调用中没有意义具体案例。

#1


Actually, the answer is yes. See Asynchronous XML Web Service Methods.

实际上,答案是肯定的。请参阅异步XML Web服务方法。

Although you create an async web method with Begin* and End* methods, .NET will only create a single operation in the WSDL. This is obvious if you think about it - what would a Java client do with an IAsyncResult?

虽然使用Begin *和End *方法创建异步Web方法,但.NET只会在WSDL中创建单个操作。如果你考虑一下这很明显 - Java客户端对IAsyncResult会做什么?

The client can call the operation synchronously or asynchronously.

客户端可以同步或异步调用操作。

#2


With the specific use-case that you provide, with a single async call, it would not be worth it, but, yes, you can invoke async calls from a web service:

使用您提供的特定用例,通过单个异步调用,它是不值得的,但是,是的,您可以从Web服务调用异步调用:

[WebMethod]
public SomeResult SynchronousMethod() {
    IAsyncResult someWork = BeginSomeAsyncWork();
    IAsyncResult otherWork = BeginOtherAsyncWork();
    WaitHandle[] all = new WaitHandle[] { someWork.AsyncWaitHandle, otherWork.AsyncWaitHandle };
    // TODO: Do some synchronous work here, if you need to 
    WaitHandle.WaitAll(all); /* this is the important part, it waits for all of the async work to be complete */
   var someWorkResult = EndSomeAsyncWork(someWork);
   var otherWorkResult = EndSomeAsyncWork(otherWork);
   // TODO: Process the results from the async work
   // TODO: Return data to the client
}

The important thing here is the WaitHandle.WaitAll, which will block until all of the async work is complete. If you can process the results individually, you could use WaitHandle.WaitAny instead, but the code gets more complicated, and is a bit out of the scope of the question.

这里重要的是WaitHandle.WaitAll,它将阻塞直到所有异步工作完成。如果您可以单独处理结果,则可以使用WaitHandle.WaitAny,但代码变得更复杂,并且有点超出了问题的范围。

#3


Yes, you're basically free to do what you want in responding to Service request. But if you only have 1 query it's not going to be of much use. If you need 2 queries or more it becomes interesting.

是的,你基本上可以*地做你想要的服务请求。但是如果你只有1个查询,它就不会有多大用处。如果您需要2个或更多查询,那就变得有趣了。


And then ofcourse you have to collect all results, as Alex Lyman points out. The ASP.NET WebPage has special support for this, that's why I'm sure it is possible.

然后当然,你必须收集所有结果,正如Alex Lyman指出的那样。 ASP.NET WebPage对此有特殊支持,这就是为什么我确信它是可行的。

#4


I don't see how this would work, when a request comes in for your webservice, a thread from the pool is going to be allocated to process the request, if you make an async call from that thread then your request thread ends and the client would not get any result back.

我没有看到这是如何工作的,当你的web服务请求进入时,来自池的线程将被分配来处理请求,如果你从该线程进行异步调用,那么你的请求线程结束并且客户不会得到任何结果。

Short Answer is No. People only seem to be reading this line and downvoting :) The user is asking if we can do an async call from inside a sync webservice call, which is certainly possible by using WaitHandles but does not make sense in the user's specific case.

简短的答案是否定的。人们似乎只是在阅读这一行并且正在低估:)用户问我们是否可以从同步webservice调用内部执行异步调用,这当然可以通过使用WaitHandles来实现,但在用户的调用中没有意义具体案例。