0

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

好的,我正在使用 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 应用程序,我们不知道用户何时会离开开始下载调用的页面以及何时会导航回该页面,因此是否应该再次调用下载处理程序。

我不知道我是否解释得当,但我希望有人能理解。谢谢你。

4

1 回答 1

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 所以一个新的调用可以获得它。

希望这可以帮助遇到类似问题的人。

服务器

于 2012-02-24T04:59:05.670 回答