событие нажатия кнопки веб-страницы .net 4.0 запускается дважды - PullRequest
0 голосов
/ 21 июня 2011

У меня есть веб-страница 4.0 с нажатием кнопки, которая запускает процесс на стороне сервера, который занимает около 5-10 секунд. Я подумал, что буду умен, и искал какой-нибудь код, который скрывал кнопку и отображал анимированное GIF-изображение во время работы процесса.
Я получил это, но начал замечать ошибки «файл используется другим процессом» выбрасывается на серверную часть (частью процесса является удаление каталога). Я прошел отладку и начал видеть то, что, казалось, было вторым нажатием кнопки при одновременном срабатывании. Оказывается, что фрагмент кода Js, который я добавил, чтобы обновить страницу, чтобы запустить анимированный GIF, кажется, запускает событие щелчка сервера во второй раз. Мне пришлось вызвать метод Js SetTimeOut (), чтобы запустить изображение GIF, именно это, кажется, вызывает проблему.
Я немного искал, чтобы попытаться найти другой подход к запуску анимированного GIF-файла, но не смог его найти, поэтому я остановился на машине скорой помощи в нижней части скалы и решил добавить метку времени на стороне сервера в сеанс и продолжайте работу с моим кодом, только если он более 20 секунд с момента последнего сеанса.
У меня были некоторые очень ошибочные результаты с этим подходом, и любой вклад будет оценен.

  1. Есть ли лучший способ, как я могу запустить gif?
  2. Кто-нибудь еще сталкивался с этой проблемой стрельбы дважды?
  3. Почему мой замок не работает с первого раза?

Любое предложение о лучшем подходе к этому приветствуется, спасибо!

Результаты регистрации:

Первый раз (сессия не существует)

2011-06-21 11: 46: 14.8968 | DEBUG | FileViewer.copyfiles | Count = 1 & Locked = False
2011-06-21 11: 46: 14.8968 | DEBUG | FileViewer.copyfiles | Count = 2 & Locked = True
2011-06-21 11: 46: 19.0619 | DEBUG | FileViewer.copyfiles | Count = 1 & Locked = False
2011-06-21 11: 46: 19.0619 | DEBUG | FileViewer.copyfiles | Count = 2 & Locked = True
2011-06-21 11: 46: 23.1959 | DEBUG | FileViewer.copyfiles | Count = 3 & Locked = True
2011-06-21 11: 46: 28.8119 | DEBUG | FileViewer.copyfiles | Count = 3 & Locked = True

Запустить снова:

2011-06-21 11: 49: 47.7798 | DEBUG | FileViewer.copyfiles | Count = 1 & Locked = False
2011-06-21 11: 49: 47.7798 | DEBUG | FileViewer.copyfiles | Count = 2 & Locked = True
2011-06-21 11: 49: 55.9697 | DEBUG | FileViewer.copyfiles | Count = 3 & Locked = True
2011-06-21 11: 49: 59.8697 | DEBUG | FileViewer.copyfiles | Count = 1 & Locked = True
2011-06-21 11: 49: 59.8697 | DEBUG | FileViewer.copyfiles | Count = 3 & Locked = True

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>

Ответы [ 4 ]

0 голосов
/ 14 марта 2015

Скорее всего, проблема заключается в том, что вы используете серверный элемент управления на стороне сервера (поскольку вы ссылаетесь на него на стороне сервера), и они запускают обратную передачу при обычном нажатии (трудно сказать, не зная точного объекта, который выИспользуешь).Используйте ввод HTML, чтобы запустить событие на стороне клиента, выполнить свою работу, а затем выполнить обратную передачу из вашего кода JS (с соответствующим идентификатором для перехвата на стороне сервера).

Что-то похожее на эту сторону сервера:

/// <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");
    }

РЕДАКТИРОВАТЬ: В качестве альтернативы я думаю, что вы также можете добавить «вернуть ложь;»после события на стороне клиента, такого как:

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

, что также должно остановить обратную передачу.

0 голосов
/ 21 июня 2011

Я подозреваю, что проблема здесь, вероятно, не имеет никакого отношения к анимированному GIF, а к нажатию кнопки дважды (т.е. два клика регистрируются вместо одного). Вы можете попробовать отключить кнопку, чтобы подавить второй щелчок (еще один способ - установить флажок на уровне кнопки) - например,

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 голосов
/ 22 июня 2011

Я решил эту проблему, поместив все соответствующие элементы управления в панель обновления. Это позволяет запустить анимированный GIF без вызова setTimeout ("UpdateImg ('MainContent_imgWait', 'Images / loading.gif');», 50);JS метод.Теперь работает нормально, событие сервера запускается только один раз.

0 голосов
/ 21 июня 2011

Я думаю, что лучше использовать некоторые инструменты веб-отладчика для отслеживания запроса.Я предлагаю использовать Fiddler

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...