2012-02-23 20 views
0

現在、私は多くの作業と検索の後に解決できない問題に直面しています。私は以前同様の質問をしましたが、それを正しく尋ねなかったので、私はその質問を削除しました。ASP.net + C#.netの相互排他的アクセス

Ok MailBEE.netオブジェクトライブラリを使用して電子メールをダウンロードしています。以前の呼び出しがまだダウンロード段階にあるときにダウンロードメソッドを再度呼び出すと、2つのメッセージのコピーが間違ってダウンロードされます。私は別のjqueryのを使用して上記の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"); 
    } 
} 

をダウンロードASHXハンドラを呼び出していますASP.netページで

(ASPX)ページ

<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の1つの呼び出しがメッセージのダウンロードでビジーで、この間に新しい呼び出しが行われた場合です。 emaのidsを見つけられないので、同じコピーのメッセージをダウンロードする前回の呼び出しが行うデータベース内に格納されます。

私は一度呼び出しがメッセージをダウンロードするのに忙しい場合、別の呼び出しを行うべきではない、相互に排他的なアクセスを必要とします。

別のコールをすることができたことを示す

if(IsAlreadyDownloading == False) 
{ 
Functions.SyncMail(params) 
} 
IsAlreadyDownloadingは1回の通話がダウンロードを開始し、それが、ダウンロード終了したり、いくつかの例外が発生した後に偽に設定されたら真を設定する必要がありますグローバルフラグやミューテックスある

ような何か安全に作った。

ASP.netアプリケーションなので、ユーザーがいつダウンロードコールを開始するか、そのページに戻るときに移動して、ダウンロードハンドラへの別の呼び出しを行う必要があるかどうかわかりません。

私が正しく説明しているかどうかわかりませんが、誰かが理解してくれることを願っています。ありがとうございました。

答えて

0

最後に、多くの髪を引っ張って頭を傷つけた後、私はこの問題を解決することができました。私はそれが最良の解決策であるかどうかわかりませんが、少なくとも今は適切に働いています。 。

私の解決策です。

私は

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

目的は行動のようなミューテックスを模倣することであり、そのために私はsync.ashxファイルを離れ、別のaspxファイルを作った、次のようにという名前のアプリケーション・レベルのグローバル変数を宣言するためのGlobal.asaxを使用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 =真見つかりますように動作しません何回我々は、このページへの呼び出しを行います終了するとIsAlreadyDownloading = falseに設定され、新しい呼び出しで取得できるようになります。

これは似たような問題の人を助けてくれるでしょう。

サーバ

関連する問題