2011-06-21 9 views
0

私は、約5〜10秒の実行にかかるサーバー側のプロセスを実行するボタンのクリックで4.0 Webページを持っています。私は賢明で、プロセスを実行している間にボタンを隠し、アニメーションGIFイメージを表示するコードを検索したいと考えました。
私はこれを動作させましたが、 "別のプロセスによって使用されているファイル"エラーがサーバー側にスローされていることに気付きました(プロセスの一部はディレクトリの削除です)。私はデバッグを行い、同時に発生した2番目のボタンイベントのクリックと思われるものを見始めました。これは、アニメーションgifを実行できるようにページを更新するために追加したJsコードが、サーバーのクリックイベントを2回目に発しているようです。私はGIFイメージを実行するためにJs SetTimeOut()メソッドを呼び出さなければなりませんでしたが、これが問題の原因と思われます。
私は、アニメーションGIFを動かすための別のアプローチを見つけようとしましたが、見つかりませんでしたので、私は崖のアプローチの最下部で救急車に行き、サーバー側を追加することに決めましたセッションにタイムスタンプを入れ、セッションが最後に設定されてから20秒以上経過している場合は、自分のコードで処理してください。
私はこのアプローチでいくつかの非常に不安定な結果を得ています。.net 4.0ウェブページボタンクリックイベントの2回の実行

  1. gifを実行するには良い方法がありますか?
  2. 他の誰かがイベントのこの問題を2回発しましたか?
  3. 私のロックが初めて機能しないのはなぜですか?

これを行うためのより良いアプローチの提案はありがたいです、ありがとう!

ロギング結果:

(既存のセッションがない)を介し

初めて

2011-06-21 11:46:14.8968 | DEBUG | FileViewer.copyfiles |ロックカウント= 1 & = Falseの
2011 -06-21 11:46:14.8968 | DEBUG | FileViewer.copyfiles | = Trueの
2011-06-21 11ロック= 2 &カウント:46:| DEBUG | 19.0619をFileViewer.copyfiles |
偽=ロック= 1 &を数えます 2011-06-21 11:46:19.0619 | DEBUG | FileViewer.copyfile | Count 46::= 2 & = trueを
2011-06-21 11ロック| DEBUG | 23.1959 FileViewer.copyfilesは| = = 3 &がロックされたカウント真
2011-06-21 11:46:28.8119 | DEBUG | FileViewer.copyfiles |再びカウント= 3 &ロック= Trueの

ラン:

2011-06-21 11:49:47.7798 | DEBUG | FileViewer.copyfilesは|カウント= 1 &ロック= Falseの
2011-06- 21 11:49:47.7798 | DEBUG | FileViewer.copyfile | Count = 2 &ロック= True
2011-06-21 11:49:55.9697 | DEBUG | FileViewer.copyfilesは| = 3 &がロックされたカウント= Trueの
2011-06-21 11:49:59.8697 | DEBUG | FileViewer.copyfilesは|カウント= 1ロック& = True
2011-06-21 11:49:59.8697 | DEBUG | FileViewer。コピーファイルは|カウント= 3 &は

protected void Page_Load(object sender, EventArgs e) 
{ 
    if (!IsPostBack) 
    { 
     PostBackOptions optionsSubmit = new PostBackOptions(btnGo); 
     btnGo.OnClientClick = "HideControlOnClick(this);"; 
     btnGo.OnClientClick += ClientScript.GetPostBackEventReference(optionsSubmit); 
    } 
} 
protected void btnGo_Click(object sender, EventArgs e) 
{ 
    bool locked = true; 

    if (Session["ClickTime"] == null || (DateTime)Session["ClickTime"] < DateTime.Now.AddSeconds(-20)) 
    { 
     Session["ClickTime"] = DateTime.Now; 
     locked = false; 
    } 

    WriteToLog(1, locked); 

    if (Page.IsValid && !locked) 
    { 
     locked = true; 

     WriteToLog(2, locked); 

     // Do all my processing 
    } 

    WriteToLog(3, locked); 
} 

<script language="javascript" type="text/javascript"> 

    function HideControlOnClick(btnGo) 
    { 
     // IE uses className for the css property.   
     btnGo.setAttribute('className', 'hide'); 

     document.getElementById('MainContent_imgWait').setAttribute('className', 'show'); 

     setTimeout("UpdateImg('MainContent_imgWait','Images/loading.gif');",50); 
    } 
    function UpdateImg(ctrl, imgsrc) 
    { 
     var img = document.getElementById(ctrl); 
     img.src = imgsrc; 
    } 
</script> 
+1

ところで、変数 'locked'を呼び出して複数のスレッドで動作させることはできません。 –

+0

はい、合意しました。そのため、セッション変数「ClickTime」に基づいて変数をロックしています。これは異なるスレッドをまたいでいる必要があります。 – Ian

+0

私はあなたが2回イベントをバインドしたと言うでしょう。aspxとコードの背後にある。 –

答えて

0

私が思う= Trueのロックされたその優れた要求を追跡するために、いくつかのWebデバッガツールを使用しています。 Fiddler

0

ここでの問題は、アニメーションgifではなく、ボタンが2回押されている(つまり、2回のクリックが1回だけ登録されてしまう)と思われます。

btnGo.OnClientClick = "return HideControlOnClick(this);"; 


function HideControlOnClick(btnGo) 
{ 
    if (btnGo["My_Is_Clicked"]) { 
     // already clicked, ignore 
     return false; 
    } 
    btnGo["My_Is_Clicked"] = true; 
    ... 
    return true; 
} 
+0

setTimeout( "UpdateImg( 'MainContent_imgWait'、 'Images/loading.gif');"、50);を削除すると、クライアントのダブルクリックとは思われません。 Jsブロックからメソッド呼び出しを呼び出すと、重複呼び出しは停止しますが、gifイメージは実行されません。 – Ian

0

は私が更新に関連するすべてのコントロールをドロップすることによって、問題を解決してきた、例えば - あなたは、第二のクリックをSUPRESSするボタンを無効にしてみてくださいすることができます(さらに別の方法では、ボタンのレベルでのフラグを持つことです)これは、アニメーションgifがsetTimeout( "UpdateImg( 'MainContent_imgWait'、 'Images/loading.gif');"、50)を呼び出さずに実行できるように思われます。 JSメソッド。一度しか起動しないサーバーイベントで正常に動作します。

0

問題は、サーバー側のボタンコントロール(サーバー側を参照しているため)を使用している可能性が高く、通常はクリックしたときにポストバックが発生しますあなたが使用しています)。 HTML入力を使用してクライアント側のイベントを発生させ、作業を行い、JSコードからポストバックを実行します(適切なIDを使用してサーバー側でキャッチします)。

このサーバ側のような何か:

/// <summary> 
/// Page init event, setup the core of the page. 
/// </summary> 
/// <param name="sender"></param> 
/// <param name="e"></param> 
protected override void Page_Init(object sender, EventArgs e) 
{ 
    try 
    { 
    // See if we're in a postback. 
    if (IsPostBack) 
    { 
     // If we have a target... 
     if (Request.Params["__EVENTTARGET"] != null) 
     { 
     // See what the target is. 
     switch (Request.Params["__EVENTTARGET"]) 
     { 
      case "btnGo": 
      // Maybe make this a parameterless method rather than an event handler to avoid parameters that you don't need. 
      btnGo_Click(null, null); 
      break; 
     } 
     } 
    } 
    } 
} 

とクライアント側:

function Go() { 
    // Show loading... 

    // Call server. 
    __doPostBack("btnGo", "My Args"); 
    } 

編集:別の方法として、私はあなたにも追加することができると思う "return false;" を

btnGo.OnClientClick = "HideControlOnClick(this); false;を返します。

また、ポストバックも停止する必要があります。