ASP.net + C#.net中的互斥访问

时间:2012-02-23 06:30:49

标签: email download synchronization locking mutual-exclusion

目前我遇到了一个问题,经过大量的工作和搜索后我无法解决,之前我问了一个类似的问题,但没有得到任何答复,可能是因为我没有正确地问它所以我删除了这个问题

好的我正在使用MailBEE.net对象库下载电子邮件,它工作正常,但如果在前一个呼叫仍处于下载阶段时再次调用下载方法,则会开始下载两个消息副本,这是错误的。

在ASP.net页面上的

我正在调用下载电子邮件的ASHX处理程序

    public class sync : IHttpHandler {
    public void ProcessRequest(HttpContext context)
    {
        ApplicationData.layer Functions = new layer();
        context.Response.ContentType = "text/text";
        int messageCount = Convert.ToInt16(context.Request.QueryString["messageCount"]);
        if (Functions.SyncMail("email", "user", "password", "pop.gmail.com", messageCount) == "Successful")
        {
            context.Response.Write("New Messages Downloaded.");
        }
        //context.Response.Write("Hello World");
    }
}

我在另一个(ASPX)页面使用Jquery调用上面的ASHX处理程序

<script type="text/javascript">
        $(document).ready(function() {
            asyncLoad();
        });
        function asyncLoad() {
            document.getElementById("CustomerDetails").innerHTML = "<img alt='' src='Images/ajax-loader.gif' />" + "&nbsp;&nbsp;<span>Downloading New Messages...</span>";
            $('#CustomerDetails').load("sync.ashx?messageCount=" + "10");
            callAgain();
        }
        function callAgain() {
            setInterval(asyncLoad, 20000);
        }
</script>

目的是在一段时间(20000延迟)之后继续调用sync.ashx以检查新消息,问题是如果sync.ashx的一个呼叫忙于下载消息并且在此期间进行了新的呼叫,它开始下载相同的邮件副本,因为它没有在数据库中找到之前调用的电子邮件ID。

我需要某种互斥访问,如果一旦呼叫忙于下载邮件,则不应进行另一次呼叫。

这样的东西
if(IsAlreadyDownloading == False)
{
Functions.SyncMail(params)
}

IsAlreadyDownloading是一个全局标志或互斥锁,一旦一个呼叫开始下载就应该设置为True,一旦完成下载就设置为false,或者发生了一些异常,表明可以安全地进行另一个呼叫。

由于它是一个ASP.net应用程序,我们不知道用户什么时候会离开开始下载调用的页面以及何时会导航回该页面,因此应该再次调用下载处理程序。 / p>

我不知道我是否正确解释了它,但我希望有人会理解。谢谢。

1 个答案:

答案 0 :(得分:0)

经过多次拔毛和头部划伤后,我设法解决了这个问题,我不知道它是否是最好的解决方案,但至少它现在正常工作,如果你知道更好的解决方案请在这里分享,谢谢。

这是我的解决方案。

我使用global.asax来声明名为的应用程序级全局变量

void Application_Start(object sender, EventArgs e) 
{
    // Code that runs on application startup
    Application["IsAlreadyDownloading"] = false;
}

目的是模仿互斥体行为,为此我离开了sync.ashx文件并制作了另一个aspx文件,从ashx文件转换的原因是访问应用程序级变量IsAlreadyDownloading,它在通用处理程序中不可用。 aspx文件的代码如下

<%@ Page Language="C#" %>
<%@ Import Namespace="ApplicationData" %>
<script runat="server">
    protected void Page_Load(object sender, EventArgs e)
    {
        int messageCount = Convert.ToInt16(Request.QueryString["messageCount"]);
        ApplicationData.layer Functions = new layer();
        try
        {
            if (!Convert.ToBoolean(Application["IsAlreadyDownloading"]))
            {
                Application["IsAlreadyDownloading"] = true;
                if (Functions.SyncMail("email", "user", "password", "pop.gmail.com", messageCount) == "Successful")
                {
                    Response.Write("New Messages Downloaded.");
                    Application["IsAlreadyDownloading"] = false;
                }
                else
                {
                    Response.Write("<p>Unable to download some messages</p>");
                    Application["IsAlreadyDownloading"] = false;
                }
            }
        }
        finally
        {
            Application["IsAlreadyDownloading"] = false;
        }
        Response.End();
    }
</script>

无论我们多少次调用此页面,该方法都无法正常工作,因为如果另一个方法调用忙于工作,它会发现IsAlreadyDownloading = true,只要它完成它将再次设置IsAlreadyDownloading = false所以新的电话可以获得它。

希望这有助于解决类似问题的人。

服务器