Currently I am facing a problem which I am unable to solve after a lot of work and search, I asked a similar question before but didn’t got any reply maybe because I didn’t asked it correctly so I deleted that question.
Ok I am downloading emails using MailBEE.net Objects library and it is working fine except that if downloading method is called again while a previous call is still in downloading phase then two copies of messages start to download which is wrong.
on an ASP.net page I am calling an ASHX handler that downloads the emails
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");
}
}
I am calling the above ASHX handler using Jquery from another (ASPX) page
<script type="text/javascript">
$(document).ready(function() {
asyncLoad();
});
function asyncLoad() {
document.getElementById("CustomerDetails").innerHTML = "<img alt='' src='Images/ajax-loader.gif' />" + " <span>Downloading New Messages...</span>";
$('#CustomerDetails').load("sync.ashx?messageCount=" + "10");
callAgain();
}
function callAgain() {
setInterval(asyncLoad, 20000);
}
</script>
The purpose is to keep on calling sync.ashx after some time (The 20000 delay) to check new messages, the problem is if one call of sync.ashx is busy in downloading messages and a new call is made during this time, it starts to download identical copies of messages since it does not find the ids of emails in database which previous call is going to make.
I need some sort of mutually exclusive access, that if once call is busy in downloading messages then another call should not be made.
Something like
if(IsAlreadyDownloading == False)
{
Functions.SyncMail(params)
}
Where IsAlreadyDownloading is a global flag or mutex that should be set True once one call start downloading and be set false once it finish downloading or some exception has occurred indicating that another call can be made safely.
Since it is an ASP.net application we don’t know when user will navigate away from the page which start download call and when it will navigate back to that page so another call to download handler should be made or not.
I don’t know if I explained it properly or not but I hope someone will understand. Thank you.
Finally after much hair pulling and head scratching I managed to solve this problem, I don’t know if it’s the best solution but at least it is working properly now, if you know a better solution please share it here, thanks.
Here is my solution.
I used global.asax to declare application level global variable named as follows
The purpose is to mimic mutex like behavior and for that I left sync.ashx file and made another an aspx file, the reason for shifting from ashx file is access application level variable IsAlreadyDownloading which is unavailable in a generic handler. The code of aspx file is as follows
No matter how many times we make call to this page the method will not work as it will find IsAlreadyDownloading = true if another call of method is busy in work, as soon as it will finish it will again set IsAlreadyDownloading = false so a new call can acquire it.
Hope this help someone in similar problem.
server