我正在做第一次試驗Comet的嘗試。我開發了一個非常簡單的聊天網絡應用程序 - 基本上是一個通過c#編寫的comet世界。我遇到的問題是IIS有時會崩潰,並通過崩潰我的意思是它只是停止響應HTTP請求。然後,它需要重新啓動應用程序池,有時還需要重新啓動整個IIS服務。我幾乎是積極的罪魁禍首是我用來阻止彗星請求線程的ManualResetEvent對象,直到收到釋放(更新)這些線程的信號。我嘗試編寫一個HTTP處理程序來解決這個問題,並將可重用屬性設置爲false(將新的請求線程置於另一個ManualResetEvent對象實例上),但這並不奏效。我也在嘗試實現IRegisteredObject,所以我可以在應用程序關閉時釋放這些內容,但這似乎也不起作用。它仍然崩潰,似乎沒有任何模式,當它崩潰(我已經注意到)。我幾乎可以肯定它是靜態實例和使用ManualResetEvent的組合。我只是不確定如何或如何解決這個問題。c#彗星服務器凍結IIS
Comet.cs(我的簡單彗星LIB)
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; }
}
}
我的聊天類和Web服務
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();
}
}
}
如果任何人有事業一個好的理論和/或修復的看似隨意的崩潰會如果you'ld後:)
謝謝!我會盡快嘗試。我有一個http處理程序,我寫了解決這個問題,但我實現了IHttpHandler(不是asnyc),所以我會definatley試一試。你認爲有可能在不創建HTTP處理程序的情況下做到這一點?我問,因爲開發一個簡單的lib可以很容易地用在像上面這樣的web servie中。 –
我沒有使用網絡服務,所以我不能說。然而,我使用IHttpAsyncHandler開發了一個彗星服務器,並且它工作得很好。 IIS/http.sys使用固定數量的線程來處理傳入的請求,如果您將它們與長時間運行或阻塞(.WaitOne)調用綁定在一起,可以很快地殺死iis。 –
這是從msdn幫助http://msdn.microsoft.com/en-us/library/aa480516.aspx鏈接?它討論了異步Web方法。 –