Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# HTTPListener在四核机器Win 2008服务器R2上崩溃_C#_Multithreading_Service_Windows Server 2008_Httplistener - Fatal编程技术网

C# HTTPListener在四核机器Win 2008服务器R2上崩溃

C# HTTPListener在四核机器Win 2008服务器R2上崩溃,c#,multithreading,service,windows-server-2008,httplistener,C#,Multithreading,Service,Windows Server 2008,Httplistener,我们基于EWS手册中的HTTPListener创建了am Exchange Web服务推送通知侦听器(代码如下)。它在Win2008服务器上使用单核xeon运行良好。现在,我们将它移动到一个带有四核opteron CPU的Win 2008 R2服务器上,在侦听器使用HTTPListenerExceptions初始化后,它立即崩溃。现在,除了服务器之外,没有任何变化,我想这可能与多线程有关。也许有人可以给你建议,谢谢 public class PushNotificationClient {

我们基于EWS手册中的HTTPListener创建了am Exchange Web服务推送通知侦听器(代码如下)。它在Win2008服务器上使用单核xeon运行良好。现在,我们将它移动到一个带有四核opteron CPU的Win 2008 R2服务器上,在侦听器使用HTTPListenerExceptions初始化后,它立即崩溃。现在,除了服务器之外,没有任何变化,我想这可能与多线程有关。也许有人可以给你建议,谢谢

public class PushNotificationClient
{
    private uint portNumber;
    private NotificationEventsReceived eventHandler;
    private bool isListening = false;
    private ManualResetEvent stopEvent = new ManualResetEvent(false);
    private bool shouldStop = false;
    private XmlNamespaceManager mgr;
    private XmlSerializer ser;

    /// <summary>
    /// Constructor
    /// </summary>
    /// <param name="portNumber">Port number to listen on</param>
    /// <param name="eventHandler">delegate to call when notifications are
    /// received</param>
    ///
    public PushNotificationClient(
    uint portNumber,
    NotificationEventsReceived eventHandler)
    {
        this.portNumber = portNumber;
        if (eventHandler == null)
        {
            throw new ArgumentNullException("eventHandler");
        }
        this.eventHandler = eventHandler;
        // namespace manager is used for XPath queries when parsing the request
        //
        this.mgr = new XmlNamespaceManager(new NameTable());
        this.mgr.AddNamespace("t",
        "http://schemas.microsoft.com/exchange/services/2006/types");
        this.mgr.AddNamespace("m",
        "http://schemas.microsoft.com/exchange/services/2006/messages");
        // XmlSerializer is used to convert SendNotification elements into proxy
        // class instances
        //
        this.ser = new XmlSerializer(typeof(SendNotificationResponseType));
    }

    /// <summary>
    /// Start Listening
    /// </summary>
    public void StartListening()
    {
        VerifyNotListening();
        this.stopEvent.Reset();
        this.shouldStop = false;
        // Run the listener on a background thread so we are not blocked
        //
        ThreadPool.QueueUserWorkItem(new WaitCallback(ListenOnThread));
    }

    /// <summary>
    /// Stop Listening
    /// </summary>
    public void StopListening()
    {
        VerifyListening();
        // Set the stopEvent. This will cause the worker thread to close our and
        // dispose of the HttpListener and exit the thread
        //
        this.stopEvent.Set();
    }

    /// <summary>
    /// Thread pool method to start listening on the background thread
    /// </summary>
    /// <param name="state">State - ignore</param>
    ///
    private void ListenOnThread(object state)
    {
        using (HttpListener listener = new HttpListener())
        {
            listener.Prefixes.Add(
                String.Format(
                "http://+:{0}/PushNotificationsClient/",
                this.portNumber.ToString()));
            listener.Start();
            this.isListening = true;
            while (!shouldStop)
            {
                IAsyncResult asyncResult = listener.BeginGetContext(
                AsyncCallbackMethod, listener);
                // Wait on either the listener or the stop event
                //
                int index = WaitHandle.WaitAny(
                new WaitHandle[] { stopEvent, asyncResult.AsyncWaitHandle });
                switch (index)
                {
                    case 0:
                        // Stop event was triggered.
                        //
                        shouldStop = true;
                        break;
                    case 1:
                        // Notification was received. Just loop around so we can call
                        // BeginGetContext again
                        //
                        break;
                }
            }
            listener.Stop();
        }
        this.isListening = false;
    }

    /// <summary>
    /// Async method called once we receive a request
    /// </summary>
    /// <param name="result">Async result containing our HttpListener</param>
    ///
    private void AsyncCallbackMethod(IAsyncResult result)
    {
        HttpListener listener = result.AsyncState as HttpListener;
        if (!this.isListening)
        {
            // Our callback gets fired when we stop the listener too. If it is not
            // listening, just return.
            //
            return;
        }
        HttpListenerContext context = listener.EndGetContext(result);
        SendNotificationResponseType request;
        // Now use the XML serializer to turn the XML into a notification
        // serialization type...
        //
        XmlDocument doc = new XmlDocument();
        try
        {
            doc.LoadXml(
            new StreamReader(
            context.Request.InputStream).ReadToEnd());
            // retrieve the first SendNotification element (there should be only one).
            //
            XmlNodeList nodes = doc.SelectNodes("//m:SendNotification[1]", this.mgr);
            if (nodes.Count == 0)
            {
                // this wasn't a SendNotification request or it was malformed or
                // something like that.
                FailRequest(context);
                return;
            }
            string sendNotification = nodes[0].OuterXml;
            using (MemoryStream ms = new MemoryStream())
            {
                byte[] bytes = Encoding.UTF8.GetBytes(sendNotification);
                ms.Write(bytes, 0, bytes.Length);
                ms.Flush();
                ms.Position = 0L;
                request = (SendNotificationResponseType)this.ser.Deserialize(ms);
            }
        }
        catch (XmlException)
        {
            // Failed to deserialize request.
            //
            FailRequest(context);
            return;
        }
        // Fire the delegate
        //
        NotificationResponse response = eventHandler(
        this, /* sender */
        request.ResponseMessages.Items[0]
        as SendNotificationResponseMessageType);
        GenerateResponseXML(context, response);
    }

    /// <summary>
    /// Fail the request. Right now we don't differentiate between reasons why it
    /// failed.
    /// </summary>
    /// <param name="context">Request context</param>
    ///
    private void FailRequest(HttpListenerContext context)
    {
        context.Response.ContentEncoding = Encoding.UTF8;
        context.Response.ContentType = "text/xml; charset=utf-8";
        context.Response.ProtocolVersion = new Version(1, 1, 0, 0);
        context.Response.StatusCode = 400;
        string response = "<?xml version=\"1.0\"?>" +
        "<Error>Bad Request</Error>";
        byte[] responseBytes = Encoding.UTF8.GetBytes(response);
        context.Response.ContentLength64 = responseBytes.Length;
        context.Response.OutputStream.Write(
        responseBytes, 0, responseBytes.Length);
        context.Response.OutputStream.Flush();
    }

    /// <summary>
    /// Generate the response xml
    /// </summary>
    /// <param name="context">call context</param>
    /// <param name="response">The response enum value</param>
    ///
    private void GenerateResponseXML(
    HttpListenerContext context,
    NotificationResponse response)
    {
        StringBuilder builder = new StringBuilder();
        builder.AppendLine("<?xml version=\"1.0\"?>");
        builder.AppendLine("<s:Envelope xmlns:s= " +
        "\"http://schemas.xmlsoap.org/soap/envelope/\">");
        builder.AppendLine("<s:Body>");
        builder.AppendLine(" <SendNotificationResult " +
        "xmlns=\"http://schemas.microsoft.com/exchange/services/2006/messages\">");
        builder.AppendFormat(" <SubscriptionStatus>{0}</SubscriptionStatus>\r\n",
        response.ToString());
        builder.AppendLine(" </SendNotificationResult>");
        builder.AppendLine("</s:Body>");
        builder.AppendLine("</s:Envelope>");
        context.Response.ContentEncoding = Encoding.UTF8;
        context.Response.ContentType = "text/xml; charset=utf-8";
        context.Response.ProtocolVersion = new Version(1, 1, 0, 0);
        context.Response.StatusCode = 200;
        byte[] responseBytes = Encoding.UTF8.GetBytes(builder.ToString());
        context.Response.ContentLength64 = responseBytes.Length;
        context.Response.OutputStream.Write(
        responseBytes, 0, responseBytes.Length);
        context.Response.OutputStream.Flush();
    }

    /// <summary>
    /// Returns true if the listener is listening
    /// </summary>
    public bool IsListening
    {
        get
        {
            return isListening;
        }
    }
    /// <summary>
    /// Verifies that the listener isn't listening
    /// </summary>
    private void VerifyNotListening()
    {
        if (isListening)
        {
            throw new PushNotificationStateException("Cannot perform this operation " +
            "when listening");
        }
    }

    /// <summary>
    /// Verifies that the listener is listening
    /// </summary>
    private void VerifyListening()
    {
        if (!isListening)
        {
            throw new PushNotificationStateException("Cannot perform this operation " +
            "when not listening");
        }
    }


}
公共类PushNotificationClient
{
专用uint端口号;
私有NotificationEventsReceivedEventHandler;
私有bool isListening=false;
private ManualResetEvent stopEvent=新的ManualResetEvent(错误);
private bool shouldStop=false;
私人空间经理;;
私有XmlSerializer;
/// 
///建造师
/// 
///要侦听的端口号
///在发送通知时要调用的委托
///收到
///
公共推送通知客户端(
uint端口号,
NotificationEventsReceived eventHandler)
{
this.portNumber=portNumber;
if(eventHandler==null)
{
抛出新ArgumentNullException(“eventHandler”);
}
this.eventHandler=eventHandler;
//命名空间管理器用于解析请求时的XPath查询
//
this.mgr=new-XmlNamespaceManager(new-NameTable());
此.mgr.AddNamespace(“t”,
"http://schemas.microsoft.com/exchange/services/2006/types");
此.mgr.AddNamespace(“m”,
"http://schemas.microsoft.com/exchange/services/2006/messages");
//XmlSerializer用于将SendNotification元素转换为代理
//类实例
//
this.ser=新的XmlSerializer(typeof(SendNotificationResponseType));
}
/// 
///开始听
/// 
公营机构
{
VerifyNotListing();
此参数为.stopEvent.Reset();
this.shouldStop=false;
//在后台线程上运行侦听器,这样我们就不会被阻止
//
QueueUserWorkItem(新的WaitCallback(ListenOnThread));
}
/// 
///别再听了
/// 
公营部门
{
验证听力();
//设置stopEvent。这将导致工作线程关闭和
//处置HttpListener并退出线程
//
this.stopEvent.Set();
}
/// 
///线程池方法开始侦听后台线程
/// 
///状态-忽略
///
私有void listenothread(对象状态)
{
使用(HttpListener=newHttpListener())
{
listener.Prefixes.Add(
字符串格式(
“http://+:{0}/PushNotificationsClient/”,
this.portNumber.ToString());
listener.Start();
this.isListening=true;
而(!应该停止)
{
IAsyncResult asyncResult=listener.BeginGetContext(
异步回调方法,侦听器);
//等待侦听器或停止事件
//
int index=WaitHandle.WaitAny(
新的WaitHandle[]{stopEvent,asyncResult.AsyncWaitHandle});
开关(索引)
{
案例0:
//已触发停止事件。
//
shouldStop=true;
打破
案例1:
//已收到通知。请循环,以便我们可以呼叫
//重新开始上下文
//
打破
}
}
listener.Stop();
}
this.isListening=false;
}
/// 
///收到请求后调用异步方法
/// 
///包含HttpListener的异步结果
///
私有void AsyncCallbackMethod(IAsyncResult结果)
{
HttpListener listener=result.AsyncState作为HttpListener;
如果(!this.isListening)
{
//当我们停止侦听器时,我们的回调也会被触发
//听着,回来吧。
//
返回;
}
HttpListenerContext=listener.EndGetContext(结果);
SendNotificationResponseType请求;
//现在使用XML序列化程序将XML转换为通知
//序列化类型。。。
//
XmlDocument doc=新的XmlDocument();
尝试
{
doc.LoadXml(
新的流阅读器(
ReadToEnd());
//检索第一个SendNotification元素(应该只有一个)。
//
XmlNodeList nodes=doc.SelectNodes(“//m:SendNotification[1]”,this.mgr);
如果(nodes.Count==0)
{
//这不是SendNotification请求,或者格式不正确或
//差不多吧。
失败请求(上下文);
返回;
}
字符串sendNotification=节点[0]。OuterXml;
使用(MemoryStream ms=new MemoryStream())
{
字节[]字节=Encoding.UTF8.GetBytes(sendNotification);
ms.Write(字节,0,字节.长度);
弗拉什女士();
ms.位置=0升;
request=(SendNotificationResponseType)this.ser.反序列化(ms);
}
}
捕获(XmlException)
{
//未能反序列化请求。
//
失败请求(上下文);
返回;
}
//解雇代表
//
NotificationResponse=eventHandler(
这是,/*发件人*/
request.ResponseMessages.Items[0]