Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Вызовы веб-методов в отдельном потоке и выгрузка файлов

33K
08 ноября 2007 года
Dmitri07
2 / / 08.11.2007
Здравствуйте, имею следующую задачку.
Необходимо по клику на ссылке скачивать файл с FTP.
Реализован веб-метод, который скачивает файл частями из FtpStream сразу отдает в виде byte[] массива.

Страничка, к которой обращаюсь, имеет адрес download.aspx?id=[ID файла]

Эта страничка имеет цикл (приближенно)


Код:
protected void Page_Load(object sender, EventArgs e)
{                    
                    Response.ClearContent();
                    Response.ClearHeaders();
                    Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlPathEncode(Path.GetFileName(filename)));
while (RequestedObjectData.OperationCode != {код окончания})
                    {
                        if (Response.IsClientConnected)
                        {
                            P.DoBufferization();
                            RequestedObjectData = P.GetObjectData();
                            if ((RequestedObjectData.OperationCode == 0))
                            {
                                Response.OutputStream.Write(RequestedObjectData.Data, 0, Length);
                                Response.Flush();
                            }
                        }
                        else
                        {
                            break;
                        }
                    }  
}

В принципе все работает. Файлик тут же отдается. НО, проблема в том, что пока этот цикл работает, больше никакой файл скачать невозможно, сам сайт стопорится и не работает, ни поиск, ни скачка, ничего.
Я попробовал организовать отдельный THREAD


 
Код:
Thread asyncThread = new Thread(new ParameterizedThreadStart(DoLongTask));              
        asyncThread.Start(System.Web.HttpContext.Current);


И соответственно запихнул код цикла в процедуру DoLongTask.

Скачивание нициализируется, протекает без проблем, проблема со "стопором" приложения решена.
Но теперь появилась проблема выгрузки на клиента. Ведь после вызова отдельного Thread для цикла страничка download.aspx програжется дальше до конца и процедура DoLongTask выдает ошибки, cannot send headers (already sent) или cannot write to Response (already closed) и так далее.


Собственно вопрос. Как можно после прогрузки страницы снова получить в свое рапоряжение Response и начать выгрузку в него двоичных данных, чтобы у клиента появилось окошечко - скачать файл.

И второй вопрос. Как вообще такое можно было бы еще организовать?
36K
27 января 2008 года
Kano
1 / / 27.01.2008
Во первых стопорится ничего не должно. Для каждого нового запроса ASP.NET и IIS6-5 создают новый поток в котором этот запрос и обслуживается.

Вероятно проблема в методах чтения данных, которые тут не представлены , возможно где то используется метод синхронизации потоков, возможно где то стоит брейкоинт :)

Еще я не понял где у тебя веб метод и где он используется?

Во вторых для подобной работы в ASP.NET предусмотренны ASHX файлы представляющие WebHandler. В твоем случае необходимо использовать асинхронные WebHandler это классы реализующие интерфейс IHttpAsyncHandler (пишу на память, примеры ищи в инете их там полно)
Почему асинхронный, а не простой IHttpHandler? Дело в том что один поток для одного длительного запроса - скачивание файла это ооочень дорого, потому что потоков у нас ограниченное количество и если они кончатся все следующие запросы будут выстраиваться в очередь, можно увеличить количество потоков, скажем до 200, но это приведет к затратам на переключение контекста между потоками и приложение будет работать не эффективно, тем более ограничение до сих пор не снято.
33K
27 января 2008 года
Dmitri07
2 / / 08.11.2007
Я могу прислать весь проект.
Посмотрите?

Очень нужно...
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог