Ситуация многопотокового обращения к странице

californie
Дата: 21.04.2007 19:04:56
Есть кусок кода, создающий некую картинку:
 objBitmap.Save(@"C:\inetpub\wwwroot\graph_cs.gif", ImageFormat.Gif);
 Img.ImageUrl = @"C:\inetpub\wwwroot\graph_cs.gif";
Предположим что страницу вызывают в один и тот же момент 100 клиентов.
Что произойдет в этом случае? будет ли картинка перезаписана самым последним из вызывавших? т.е. если рисунок картинки различен по построению для каждого из 100 клиентов, то не получится ли что последний перепишет картинку и все 100 клиентов получат его картинку?
Если да, то как избежать такой ситуации?
hamster
Дата: 21.04.2007 19:39:52
Ну прикрепляй к имени файла, который ты сохраняешь какой нибудь параметр, например идентификатор сессии, тогда у каждого юзера точно будет сохраняться свой файл.
Программеры курят быстро. Потому что мысль. Потому что она уйдет и придется думать ее снова...
prokhorovserge
Дата: 21.04.2007 20:03:07
Я обычно добавляю timestamp, типа:
imgUrl = "Temp/Images/" + barFileName + "?date=" + date.getUTCMilliseconds(); // to break image caching
Serge
californie
Дата: 21.04.2007 21:06:10
>imgUrl = "Temp/Images/" + barFileName + "?date=" + date.getUTCMilliseconds(); // to break image caching
тут фишка в том , что мне также нет ризона хранить туеву кучу этих темп файлов и писать для них дополнительный сервис который бы их удалял (хотя конечно можно удалять сразу после отображения из кода...).
файл мне нужен на очень короткий промежуток времени: создал файл, отобразил на странице и все , дальше он может быть удален (я полагаю это не повлияет на то что уже отображено на странице?).
для того чтобы не было проблем, я думаю надо просто как то заблокировать ресурс до того как выведу файл на страницу.
как это можно сделать? я так понимаю что используя блокировку будет решена проблема индивидуальных файлов для каждого клиента, не так ли?
какой из этих 2х вариантов будет лучше: индивидуальное имя и удаление после отображения или общее имя , и блокировка до вывода?
также вопрос: если файл записывается в вирт. директ. проекта, то не нарушает ли это безопасность проекта?

 
VERS
Дата: 21.04.2007 21:21:20
Отдавайте не сохраняя в файл и все вопросы отпадут.
-------------------------------
www.free-lancer.ru
californie
Дата: 21.04.2007 21:24:59
а пример кода можно?
prokhorovserge
Дата: 21.04.2007 23:29:29
Слить имидж в массив байтов и this.Response.BinaryWrite.
Serge
zoldat
Дата: 22.04.2007 00:26:04
В связи с тем, что есть вопросы на "Отдавайте не сохраняя в файл и все вопросы отпадут", считаю надо дать развернутый ответ.

Блокировка крайне нежелательна (она кстати и так будет, при одновременом запросе на эту ASP-страницу, при записи файла, я думаю даже падение типа access denied ASP-потоков, кроме одного, того который пишет).
Я так понимаю на основе каких-то пользовательских данных вами генерируются картинки. В этом случае, процесс генерации лучше перенести с этапа обработки запроса браузера на получение HTML-кода страницы, на этап обработки запроса браузера на получение картинки. То есть, именно так как вам сказал VERS (Отдавайте не сохраняя в файл и все вопросы отпадут). Как это сделать?
Пишите свой HTTP-обработчик, который и будет обрабатывать запрос браузера на получение картинки. Для этого вы пишите класс реализующий интерфейс System.Web.IHttpHandler. Естественно пользовательские данные, на основе которых вы генерируете картинку должны быть закодированы в URL картинки. Главный метод который надо реализовать это ProcessRequest.

public void ProcessRequest(HttpContext context)
 {
   //Считываем пользовательские данные 
   ParseUserData(context.Request.QueryString);
   //Говорим браузеру формат передаваемых данных
   context.Response.ContentType = "image/gif";
   //Генерируем картинку
   Image image = GenerateImage();
   //Выводим ее в выходной поток
   image.Save(context.Response.OutputStream, ImageFormat.Gif);
  context.Response.Flush();
}

Чтобы обработка запроса работала надо прописать HTTP-обработчик в Web.config. Надо задать URL обработчика. Стандартное расширение для таких HTTP-обработчиков ashx. К примеру назовем обработчик image.ashx. Допустим класс обработчика называется ImageGeneratorLibrary.ImageGenerator и находится он в dll-ке ImageGeneratorLibrary.dll, тогда для прописки HTTP-обработчика в разделе system.web\httpHandlers создаем элемент
<add verb="GET" path="image.ashx" type="ImageGeneratorLibrary.ImageGenerator, ImageGeneratorLibrary" />.
В коде ASP-страницы оставляем только установку URL у картинки: Img.ImageUrl="image.ashx?{закодированные данные пользователя в URL}";

P.S. Первое. Конечно некоторые аспекты в коде такие как обработка ошибок для ясности опущены.
Второе. Если юзер передает в ASP-форму свой файл картинки, на основе которого генерируется выходная картинка, то конечно же данное решение не подходит, т.к. нельзя будет закодировать URL картинки. Однако и на этот случай есть приемлемое решение.
californie
Дата: 22.04.2007 00:34:36
prokhorovserge:
Слить имидж в массив байтов и this.Response.BinaryWrite.

Здесь есть большая проблема.
У меня на страничке есть разные контролы, таблицы и т.д.
рисунок мне надо вывести в строго определенном месте.
С одной стороны непонятно куда поместить кусок кода чтобы рисунок выводился в нужном месте.
а с другой стороны поместив код в Page_Load у меня выводится только этот рисунок и ничего более.
Вот код:
//   MemoryStream ms = new MemoryStream();
//   objBitmap.Save(ms,System.Drawing.Imaging.ImageFormat.Bmp);
//   this.Response.BinaryWrite(ms.GetBuffer());

Каким же тогда образом вывести рисунок правильно и не потерять другие контролы?
Сергей Чернов
Дата: 22.04.2007 00:38:53
Вы можете вывести или контролы (text/html) или картинку (image/jpeg к примеру) - одновременно нельзя. Решение - отдельная страница или хэндлер для вывода исключительно картинки. А дальше делаете {img src="ImageHandler.aspx?id=13"}