Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Разработка под ASP.NET > Как выполнить код 1 раз?


Автор: alir 14.10.2005, 16:24
Мне нужно, чтобы некоторая часть кода выполнилась 1 раз (при 1 запуске странице), остальная - неважно. Есть такое свойство?

Автор: arilou 14.10.2005, 16:28
Код

if(!IsPostBack)
{
  // do something
}


выполнится один раз

Автор: alir 14.10.2005, 16:58
Не все так просто.
Если помесить код в postback вот что происходит:
Код

public ArrayList list;
private void Page_Load(object sender, System.EventArgs e)
{ 
  if (!IsPostBack)
 {
    list = new ArrayList();
    // считывание из файла в list
 }
}
private void ImageButton1_Click(object sender, System.Web.UI.ImageClickEventArgs e)
{
if (list.Contains(lstProduce.SelectedItem.ToString()))  // - вылетает на этой строчке
    return;
else
{
    list.Add(lstProduce.SelectedItem.ToString());
        //пишем в файл содержимое list
}
}


Ошибка: Object reference not set to an instance of an object.


Если же код с заполнением list'a из postback вытащить, но оставть в PageLoad, то сначал все пройдет наромально, но потом он, после действий с формой, вылетет с ошибкой:
The process cannot access the file "..." because it is being used by another process.
А вылетает при создании StreamReader reader = file.OpenText(); - потому и хотел его выполнять 1 раз.

Автор: Mad 14.10.2005, 17:57
Цитата(alir @ 14.10.2005, 15:58)
The process cannot access the file "..." because it is being used by another process.
А вылетает при создании StreamReader reader = file.OpenText(); - потому и хотел его выполнять 1 раз.

код чтения, тебе всетаки придеться выполнять при каждом обращении к странице, вот только внимательно помотри, после чтения ты вызываеш reader.Close() или нет ?smile

Автор: alir 14.10.2005, 18:00
Mad
Конечно, вызываю. Вот только потоки каким-то образом накладываются.

Автор: Mad 14.10.2005, 18:10
alir
Вообщето не имеет значения, вызываеш или нет (сори, перед этом я просто прикололся smile)
С обновлением файлов в ASP.NET вообще тяжко работать (не не расыитана она на это, предпологаеться что все будет через базы идти).
Если ты храниш какието данные в файле, то представь себе ситуацию, один юзер только заходит на страницу,а второй ее уже обновляет. И как системма будет одновременно читать, и перезаписывать один и тотже файл ? smile

Автор: alir 14.10.2005, 18:47
Свел проблему к миниму:
Код

private void ImageButton1_Click(object sender, System.Web.UI.ImageClickEventArgs e)
        { 
            string nameFile = Application["File"].ToString();
                ArrayList list= new ArrayList();
           //считывание сторк из файла и заполнение их в listBox
            FileInfo file = new FileInfo(nameFile);
            StreamReader reader2 = file.OpenText();
            string str;    
            list = new ArrayList();
            while(reader2.Peek() >= 0)    
            {    
                str = reader2.ReadLine();
                list.Add(str);
            }
            reader2.Close();
           //запись в файл содержимого listBox'a
            FileStream fs = new FileStream(nameFile, FileMode.OpenOrCreate, FileAccess.Write);
            StreamWriter w = new StreamWriter(fs);
            string s;
            if (list.Contains(lstProduce.SelectedItem.ToString()))
            {
                lit1.Text ="Выбранный товар уже имеется в корзине.";
                return;
            }
            else
            {
                list.Add(lstProduce.SelectedItem.ToString());
                foreach (string item in list)
                {
                    w.WriteLine(item);
                }
                w.Flush();
                w.Close(); 
                lit1.Text="Выбранный товар добавлен в корзину.";
            }
        } 


после 4-5 выполнения это функции вылетает ошибка:
Цитата

The process cannot access the file "c:\inetpub\wwwroot\Store\users_files\user_Store.txt" because it is being used by another process.

Вылетает на: StreamReader reader2 = file.OpenText();

Почему??? Накладываются потоки?

Автор: Mad 14.10.2005, 18:54
Цитата(alir @ 14.10.2005, 17:47)
            FileStream fs = new FileStream(nameFile, FileMode.OpenOrCreate, FileAccess.Write);
            StreamWriter w = new StreamWriter(fs);
            string s;
            if (list.Contains(lstProduce.SelectedItem.ToString()))
            {
                lit1.Text ="Выбранный товар уже имеется в корзине.";
                return;
            }
            else
            {
                list.Add(lstProduce.SelectedItem.ToString());
                foreach (string item in list)
                {
                    w.WriteLine(item);
                }
                w.Flush();
                w.Close();
                lit1.Text="Выбранный товар добавлен в корзину.";
            }

Попробуй так :
Код

  //          FileStream fs = new FileStream(nameFile, FileMode.OpenOrCreate, FileAccess.Write);
            StreamWriter w = new StreamWriter(nameFile, false);
            string s;
            if (list.Contains(lstProduce.SelectedItem.ToString()))
            {
                lit1.Text ="Выбранный товар уже имеется в корзине.";
            }
            else
            {
                list.Add(lstProduce.SelectedItem.ToString());
                foreach (string item in list)
                {
                    w.WriteLine(item);
                }
                w.Flush();
                lit1.Text="Выбранный товар добавлен в корзину.";
            }
            w.Close(); 

а то у тебя закрытие стрима не всегда выполнялось ;) (не во всех if ветках)
но этот код всеравно будет работать неустойчиво, при заходенескольких пользователей на эту страницу, он будет давать туже ошибку.
Чтоб этого избежать можеш попробывать так (хотя и немного коряво smile ):
Код

while(true)
{
    try
   {
            FileInfo file = new FileInfo(nameFile);
            StreamReader reader2 = file.OpenText();
            string str;    
            list = new ArrayList();
            while(reader2.Peek() >= 0)    
            {    
                str = reader2.ReadLine();
                list.Add(str);
            }
            reader2.Close();
            break;
    }
    catch(Exception)
    {
    }
}

Автор: alir 14.10.2005, 19:53
Mad
Цитата
Чтоб этого избежать можеш попробывать так

Ну вроде работает, правда, если быстро нажимать, начинает долго думать.
Все же спасибо.

Автор: Mad 15.10.2005, 12:34
Цитата(alir @ 14.10.2005, 18:53)
если быстро нажимать, начинает долго думать.

от этого тебе не уйти (толко переход на БД).

Автор: arilou 17.10.2005, 16:03
Цитата(alir @ 14.10.2005, 16:58)
Не все так просто.
Если помесить код в postback вот что происходит:

код C#
public ArrayList list;
private void Page_Load(object sender, System.EventArgs e)
{
  if (!IsPostBack)
{
    list = new ArrayList();
    // считывание из файла в list
}
}


Так. Налицо некоторое непонимание жизненного цикла страницы.

Как известно, HTTP - протокол "без состояния". Всякие session, view state и проч. - это уже навороты каждой отдельно взятой среды (ASP.NET, PHP, Java, etc). В ASP.NET страница проходит следующие этапы в своем жизненном цикле:

1. Page init
2. Page load
3. Обработка postback'ов (если они были)
4. Page pre-render
5. Page unload

После п.5 страница перестает существовать. Инстанса твоего class MySuperPage : System.Web.UI.Page уже нет. Поэтому,

1. Инстансы всех классов (list = new ArrayList();!!!!!) должны создаваться при каждой инициализации страницы.
2. Другое дело - заполнение контролов значениями и data binding - это должно происходить только в те моменты, когда это тебе нужно. Например, при первом обращении к странице (if(!IsPostBack))

Далее, ты работаешь с файлом. Как правильно заметил Mad, в веб-приложении это совсем не хорошо, потому что веб-приложение априори многопоточное, и программировать под него надо принимая это во внимание. Так что тебе нужно использовать какой-то механизм синхронизации доступа к файлу. Иначе будет:
Цитата(alir @ 14.10.2005, 18:00)
Вот только потоки каким-то образом накладываются


Переходи на работу с БД. Если же ну никак без файла, то тогда хотя бы не давай нескольким пользователям его модифицировать, иначе будешь получать ошибки
Цитата
The process cannot access the file "..." because it is being used by another process.


Вот такие, брат, дела.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)