【问题标题】:Are WebServices asynch/synch on .NET?.NET 上的 Web 服务是异步/同步的吗?
【发布时间】:2013-12-03 15:39:41
【问题描述】:

我从客户端调用了 30 次 WebService 方法(asmx):

for (var i = 0; i < 30; i++) {
    WSCustom.Test(i,
        function (res) {
            $("#Results").append(res + "<br />");
        }, 
        function (res) { 
            $("#Results").append(res.get_message() + "<br />"); 
        }
    );
}

这是 WebService 方法:

[WebMethod(EnableSession = true)]
public string Test(int i)
{
    DateTime m_oStart = DateTime.Now;
    WebClient m_oClient = new WebClient();

    if (i % 2 == 0)
    {
        byte[] res = m_oClient.DownloadData("http://www.repubblica.it/");
    }

    return String.Format("TotalSeconds:{0}", new string[] { DateTime.Now.Subtract(m_oStart).TotalSeconds.ToString() });
}

我关注的是异步回复。

我的意思是,我应该立即收到 15 条回复(奇数 i 它会立即返回),而在此期间其他回复(需要时间下载页面服务器端)。

但实际上,输出是不同的:它立即处理第一个调用。然后,它等待第二个完成,然后我收到一些奇怪的i 回复,等等。

所以它根本不是异步的。

WebServices 如何在 .NET 中管理客户端调用?我可以异步执行整个过程吗?

编辑

使用EnableSession = false,结果如下:

TotalSeconds:0
TotalSeconds:0
TotalSeconds:0
TotalSeconds:0
TotalSeconds:0
TotalSeconds:1,514
TotalSeconds:0
TotalSeconds:1,857
TotalSeconds:0
TotalSeconds:2,143
TotalSeconds:0
TotalSeconds:1,88
TotalSeconds:0
TotalSeconds:3,178
TotalSeconds:0
TotalSeconds:3,562
TotalSeconds:2,095
TotalSeconds:0
TotalSeconds:0
TotalSeconds:4,221
TotalSeconds:1,749
TotalSeconds:0
TotalSeconds:0
TotalSeconds:3,717
TotalSeconds:0
TotalSeconds:1,977
TotalSeconds:2,421
TotalSeconds:2,439
TotalSeconds:1,807
TotalSeconds:2,124

所以这不是会话错误。

【问题讨论】:

  • 首先,不要使用DateTime来衡量程序的运行时间;它没有足够的精度。使用StopWatch

标签: c# .net web-services asynchronous


【解决方案1】:

您的网络方法中有EnableSession=true。这实际上是将调用排队,因为会话对象将为每个请求锁定。

如果你没有使用会话,那么你不应该启用它。


来自http://msdn.microsoft.com/en-us/library/aa478952.aspx

为了提供 GetItemExclusive 要求的排他性,一个 会话状态提供者必须实现一种锁定机制 防止给定会话被两个或多个并发访问 需要对会话状态进行读/写访问的请求。那个机制 通过防止并发,确保会话状态的一致性 请求覆盖彼此的更改。锁定机制 即使会话状态数据源是远程资源也必须工作 由多个 Web 服务器共享。

【讨论】:

  • 这是主要问题,但Servy的回答中提出的观点也很相关。您的浏览器不会像那样发出 15 个并发请求。
  • 不是 100% 确定您最终想要做什么,但您可以对服务器进行一次 AJAX 调用,并让该调用使用 TPL 将您的多个请求排队并在所有请求完成后返回回应。它们不一定会同时运行,具体取决于您的线程池的设置方式,但会比从浏览器发出 30 个请求更快。
【解决方案2】:

它是异步的,因为该方法不会在 javascript 中阻塞,而是在操作完成时触发回调。

它可能是也可能不是并行,这与异步不同。

请注意,大多数浏览器都会对发出的并发 AJAX 请求数附加限制。您当然不能一次发送 30 个请求。一般来说,你只会看到几个,1-3 个左右。这就是为什么您通常会按顺序查看所有请求,而不是所有请求都在同一时间返回。

【讨论】:

  • @markzzz 如果您愿意,您可以使用一个工具来嗅探您自己的网络流量,以便自己查看。浏览器很可能表明它收到了执行 AJAX 查询的请求,这并不意味着它当时就发出了网络请求。
【解决方案3】:

WebService 是默认的线程。 如果您有问题尝试在连接字符串中插入 Pool Size=10 或更多, 请注意,如果您有一个通用的对象使用:

 lock (myObjList)
            {
                ...
            }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多