c#comet服务器冻结IIS

本文关键字:IIS 冻结 服务器 c#comet | 更新日期: 2023-09-27 17:59:42

我第一次尝试彗星。我开发了一个非常简单的聊天网络应用程序——基本上是一个通过c#的彗星你好世界。我遇到的问题是IIS有时会崩溃,我所说的崩溃只是指它停止响应HTTP请求。然后需要永远重新启动应用程序池,有时还需要重新启动整个IIS服务。我几乎可以肯定,罪魁祸首是我用来阻止comet请求线程的ManualResetEvent对象,直到收到释放(更新)这些线程的信号。我尝试编写一个HTTP处理程序来解决这个问题,并将可重用属性设置为false(将新的请求线程放在ManualResetEvent对象的另一个实例上),但没有成功。我也在尝试实现IRegisteredObject,这样我就可以在应用程序关闭时释放这些thead,但这似乎也不起作用。它仍然会崩溃,而且崩溃时似乎没有任何模式(我注意到了)。我几乎可以肯定是静态实例和使用ManualResetEvent的结合造成了这种情况。我只是不知道如何或如何修复它。

Comet.cs(我的简单彗星库)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Net.Mail;
using System.Web.Hosting;
namespace Comet
{
    public class CometCore : IRegisteredObject
    {
        #region Globals
        private static CometCore m_instance = null;
        private List<CometRequest> m_requests = new List<CometRequest>();
        private int m_timeout = 120000; //Default - 20 minutes;
        #endregion
        #region Constructor(s)
        public CometCore()
        {
            HostingEnvironment.RegisterObject(this);
        }
        #endregion
        #region Properties
        /// <summary>
        /// Singleton instance of the class
        /// </summary>
        public static CometCore Instance
        {
            get
            {
                if (m_instance == null)
                    m_instance = new CometCore();
                return m_instance;
            }
        }
        /// <summary>
        /// In milliseconds or -1 for no timeout.
        /// </summary>
        public int Timeout { get { return m_timeout; } set { m_timeout = value; } }
        #endregion
        #region Public Methods
        /// <summary>
        /// Pauses the thread until an update command with the same id is sent.
        /// </summary>
        /// <param name="id"></param>
        public void WaitForUpdates(string id)
        {
            //Add this request (and thread) to the list and then make it wait.
            CometRequest request;
            m_requests.Add(request = new CometRequest(id));
            if (m_timeout > -1)
                request.MRE.WaitOne(m_timeout);
            else
                request.MRE.WaitOne();
        }
        /// <summary>
        /// Un-pauses the threads with this id.
        /// </summary>
        /// <param name="id"></param>
        public void SendUpdate(string id)
        {
            for (int i = 0; i < m_requests.Count; i++)
            {
                if (m_requests[i].ID.Equals(id))
                {
                    m_requests[i].MRE.Set();
                    m_requests.RemoveAt(i);
                    i--;
                }
            }
        }
        #endregion
        public void Stop(bool immediate)
        {
            //release all threads
            for (int i = 0; i < m_requests.Count; i++)
            {
                m_requests[i].MRE.Set();
                m_requests.RemoveAt(i);
                i--;
            }
        }
    }
    public class CometRequest
    {
        public string ID = null;
        public ManualResetEvent MRE = new ManualResetEvent(false);
        public CometRequest(string pID) { ID = pID; }
    }
}

我的聊天课和网络服务

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using Comet;
namespace CometTest
{
    /// <summary>
    /// Summary description for Chat
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    [System.Web.Script.Services.ScriptService]
    public class Chat : System.Web.Services.WebService
    {
        [WebMethod]
        public string ReceiveChat()
        {
            return ChatData.Instance.GetLines();
        }
        [WebMethod]
        public string ReceiveChat_Comet()
        {
            CometCore.Instance.WaitForUpdates("chat");
            return ChatData.Instance.GetLines();
        }
        [WebMethod]
        public void Send(string line)
        {
            ChatData.Instance.Add(line);
            CometCore.Instance.SendUpdate("chat");
        }
    }
    public class ChatData
    {
        private static ChatData m_instance = null;
        private List<string> m_chatLines = new List<string>();
        private const int m_maxLines = 5;
        public static ChatData Instance
        {
            get
            {
                if (m_instance == null)
                    m_instance = new ChatData();
                return m_instance;
            }
        }
        public string GetLines()
        {
            string ret = string.Empty;
            for (int i = 0; i < m_chatLines.Count; i++)
            {
                ret += m_chatLines[i] + "<br>";
            }
            return ret;
        }
        public void Add(string line)
        {
            m_chatLines.Insert(0, line);
            if (m_chatLines.Count > m_maxLines)
            {
                m_chatLines.RemoveAt(m_chatLines.Count - 1);
            }
        }
    }
}

测试aspx文件

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="CometTest.Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server">
            <Services>
                <asp:ServiceReference Path="~/Chat.asmx" />
            </Services>
        </asp:ScriptManager>
        <div id="lyrChatLines" style="height: 200px; width: 300px; border: 1px solid #cccccc; overflow: scroll">
        </div>
        <asp:Panel runat="server" DefaultButton="cmdSend">
            <asp:UpdatePanel runat="server">
                <ContentTemplate>
                    <asp:TextBox style="width: 220px" runat="server" ID="txtChat"></asp:TextBox>
                    <asp:Button runat="server" ID="cmdSend" Text="Send" OnClick="cmdSend_Click" />
                </ContentTemplate>
            </asp:UpdatePanel>
        </asp:Panel>
        <script type="text/javascript">
            function CometReceive()
            {
                CometTest.Chat.ReceiveChat_Comet(receive, commError, commError);
            }
            function ReceiveNow()
            {
                CometTest.Chat.ReceiveChat(receive, commError, commError);
            }
            function receive(str)
            {
                document.getElementById("lyrChatLines").innerHTML = str;
                setTimeout("CometReceive()", 0);
            }
            function commError()
            {
                document.getElementById("lyrChatLines").innerHTML =
                    "Communication Error...";
                setTimeout("CometReceive()", 5000);
            }
            setTimeout("ReceiveNow()", 0);
        </script>
    </form>
</body>
</html>

以及背后的aspx代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace CometTest
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }
        protected void cmdSend_Click(object sender, EventArgs e)
        {
            Chat service = new Chat();
            service.Send
            (
                Request.UserHostAddress + "> " +
                txtChat.Text
            );
            txtChat.Text = string.Empty;
            txtChat.Focus();
        }
    }
}

如果有人对这些看似随意的崩溃的原因和/或修复方法有很好的理论,如果你发布以下内容,我们将不胜感激:)

c#comet服务器冻结IIS

这个问题.NETComet引擎有一些链接应该为您指明正确的方向。您需要考虑实现一个IHttpAsyncHandler来处理长时间运行的comet请求。