出乎意料的同步运行的Web服务 [英] Web service running unexpectedly synchronously

查看:126
本文介绍了出乎意料的同步运行的Web服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们已经得到了需要连接到一个缓慢的数据库进程,并返回一个值给客户端,因此试图异步运行它停止它阻塞线程Web服务。但是,如果我们两次调用它们会依次运行,而不是异步的。调用1返回5秒钟后,通话2 10后,调用3月15日以后依此类推。

We've got a web service that needs to connect to a slow database process and returns a value to the client, so are trying to run it asynchronously to stop it blocking the thread. However, if we make two calls they run sequentially, not asynchronously at all. Call 1 returns after 5 seconds, call 2 after 10, call 3 after 15 and so on.

这里是(简化测试版)code -

Here's the (simplified test version) code -

public class ImportAsyncController : AsyncController
{
    [HttpPost]
    [Authorize(Roles = "Admin, ContentAdmin, ContentEdit")]
    public async Task<string> SlowProcess()
    {
        await Task.Delay(5000);
        return "Hello, world!";
    }
}

IIS 7.5,默认设置。传统项目,所以不是完全不可能有在的迫使其项目文件的东西在其他地方,但不知道是什么,对不起。

IIS 7.5, default settings. Legacy project so not completely impossible there's something elsewhere in the project file that's forcing it but no idea what, sorry.

有关引用的真正code,这是从调用一个SQL存储过程服务器减少。有内部使用sp_getapplock并发逻辑和运行SSMS时正确返回 - 1调用运行到结束,调用> 1返回错误code如果调用1仍在运行或本身完成,如果事实并非如此。这逻辑是罚款;真正的问题是,正在按顺序处理队列中的Web请求这么称呼> 1甚至不调用,直到通话1已完成。

For reference the real code that this was cut down from calls an SQL server sproc. That has concurrency logic internally using sp_getapplock and returns correctly when run in SSMS - call 1 runs to completion, call >1 returns an error code if call 1 is still running or itself completes if it is not. That logic is fine; the problem really is that the web requests are being processed sequentially in a queue so call >1 isn't even called until call 1 has completed.

什么是我们做错了什么?

What are we doing wrong?

推荐答案

这可以,如果你动作写入会话发生。基本上,Session对象将被锁定,直到请求完成这给同步调用的错觉。

This can happen if you action is writing to the Session. Basically the Session object will be locked until the request is finished which gives the illusion of a synchronous call.

示例

由于以下行动写入会话直到请求完成将锁定会话对象(5秒钟后)。如果你要调用来自客户端的这一行动异步将5秒,10秒,15秒等后返回。

Since the following Action writes to the session it will lock the session object until the request has finished (after 5 seconds). If you were to calls this action async from the client it would return after 5 seconds, 10 seconds, 15 seconds etc.

public async Task<string> SlowProcess() {

    Session["Hello"] = "World";

    await Task.Delay(5000);
    return "Hello, world!"; 

}

解决方案

如果您需要使用session对象,你可以告诉控制器使用应prevent会话锁定只读模式。要做到这一点,你使用 SessionStateBehaviour 属性上控制器(未操作)。

If you need to use the session object you can tell the controller to use ReadOnly mode which should prevent the session being locked. To do this you use the SessionStateBehaviour attribute on the controller (Not the action).

您将有一些看起来像这样...

You will have something that looks like this...

[SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]
public class HomeController : Controller
{


    public async Task<string> SlowProcess()
    {

        Session["Hello"] = "World";

        await Task.Delay(5000);
        return "Hello, world!";
    }


}

希望这有助于。

更新

我发现了一个很好的文章,其中介绍了您可能会发现有用的问题。快来看看吧!

I found a good article which explains the issue that you might find useful. Check it out!

http://johnculviner.com/asp-net-concurrent-ajax-requests-and-session-state-blocking/

这篇关于出乎意料的同步运行的Web服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆