似乎服务方法实际上并不是异步调用的

时间:2012-05-10 11:19:16

标签: silverlight

关于我以前的帖子:910220 - service methods run dependently 因为代码以及我对它所遇到的问题的意义有点复杂,我再次使用完全改变的代码来解释自己更好。

在客户方面,我们有:

#define USE_ONLY_ONE_INSTANCE

using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using CountTester.ServiceReference1;

namespace CountTester
{
    public partial class MainPage : UserControl
    {
#if USE_ONLY_ONE_INSTANCE
        private readonly Service1Client _sc = new Service1Client();
#endif

        public MainPage()
        {
            InitializeComponent();
#if USE_ONLY_ONE_INSTANCE
            _sc.CountCompleted += OnCountCompleted;
#endif
        }

        void OnCountCompleted(object sender, AsyncCompletedEventArgs e)
        {
            if (e.Error != null)
                throw new Exception(string.Format("Count Error {0}", e.Error));
        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            for (int i = 0; i < 100; i++)
            {
#if USE_ONLY_ONE_INSTANCE
                _sc.CountAsync(i);
#else
                var sc = new Service1Client();
                sc.CountCompleted += OnCountCompleted;
                sc.CountAsync(i);
                //sc.CloseAsync();
#endif
            }
        }
    }
}

这是XAML背后的代码。在代码中我调用了一次服务方法100次。我尝试了两种情况并在两种情况下都获得了异常: 案例1:我只使用一个代理实例进行与服务器的所有通信。 案例2:我使用一个实例与服务器进行每次通信。

让我们在更多描述之前看一下服务器上的代码:

using System.IO;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Text;
using System.Threading;

namespace CountTester.Web
{
    [ServiceContract(Namespace = "")]
    [SilverlightFaultBehavior]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class Service1
    {
        const string logFileName = @"h:\CountTester.log";
        object _logLock = new object();

        void log(string s)
        {
            lock (_logLock)
            {
                var streamWriter = new StreamWriter(logFileName, true, Encoding.ASCII);
                streamWriter.Write(s);
                streamWriter.Close();
            }
        }

        Service1()
        {
            //File.Delete(logFileName);
        }

        [OperationContract]
        public void Count(int counter)
        {
            log(string.Format("{0}\n", counter));
            Thread.Sleep(3000);
        }
    }
}

Count是被调用的服务方法。我故意在方法中等待3秒钟。我期待的是客户端的服务能够毫不拖延地完成。我希望该方法被异步调用,这意味着第一次调用不会影响第二次调用。

换句话说,如果我调用该方法并等待完成,再次调用它不会延迟。

虽然情况确实如此。怎么能弄清楚这会发生什么?通过使用Tail for Windows,我发现记录的数字在记录时被延迟。当我看到响应调用服务方法(Count Error ...)时出现异常时,我也弄明白这一点。我希望我能澄清一下我的问题。

当我取消注意我已关闭服务的行时,我也想知道当我看到程序出现故障(例外)的时候?

请回答这两个问题。

1 个答案:

答案 0 :(得分:0)

问题1:

默认情况下,IIS Web服务只允许来自同一IP地址的2个同时请求。此限制是默认停止DOS(拒绝服务)攻击。

这意味着后续的98个呼叫每对等待至少3秒,而之前的呼叫完成。最终,您将在处理最后一个请求之前很久就达到默认的30秒(?)服务器超时。

如果您坚持要运行那么多同时请求(不管怎么说),则需要增加服务器上web.config文件中的默认限制。 See my other answer here for more details

问题2:

启动后不应立即关闭异步呼叫...呼叫仍在进行中。那段代码毫无意义。

说明:

为了提高效率,无论如何都会延迟记录,因此请不要将其作为指南。