سلام
آیا کسی راهی برای این مسئله می داند؟
سلام
آیا کسی راهی برای این مسئله می داند؟
طرز استفادش را میگی سالار جان ؟
این نمونه طرز استفاده رو نشون می ده.
DownloadFile("c:\\file.txt");
private void DownloadFile(string fileName)
{
try
{
byte[] downData;
int fileLen;
FileStream file = File.OpenRead(fileName);
try
{
fileLen = Convert.ToInt32(file.Length);
downData = new byte[fileLen];
file.Read(downData, 0, fileLen);
}
finally
{
if (file != null)
{
file.Close();
file.Dispose();
}
file = null;
}
string fileHeaderName = Path.GetFileName(fileName).Replace(' ', '-');
ResumableDownload downloader = new ResumableDownload();
downloader.ClearResponseData();
DownloadState downState = downloader.ProcessDownload(downData, fileHeaderName, fileHeaderName);
System.Diagnostics.Debug.WriteLine("\nDownloadStat e=" + downState.ToString());
downData = null;
if (downState == DownloadState.fsDownloadFinished)
{
// Do somthing
}
}
catch (System.Threading.ThreadAbortException)
{
// Nothing
}
}
سالار جان دست شما درد نکنه
ولی یک مشکل ، این کار شما برای فایل 20 مگی خوبه چون فایل را درون پروسس ASP.NET لود میکند و رم سرور با این کار پر میشود
فایل های من 700 مگی هستند
شما از این استفاده کردید
objResponse.OutputStream.Write(bBuffer, 0, iLengthOfReadChunk);
ولی برای اینکه فایل درون رم سرور لود نشود بنا به تاپیک زیر
http://forums.asp.net/p/1125626/1839693.aspx#1839693
باید از
TransmitFile()
استفاده کنیم
شما نظرتون چیست ؟
اگه به خط بعدی نگاه کنی نابع Flush استفاده شده. این تابع بافر جاری رو به کاربر ارسال می کنه.شما از این استفاده کردید
و این مانع مشکلی که گفتی خواهد شد.
TransmitFile ذاتا از resume پشتیانی نمی کنه.بنا به تاپیک زیر
در اون تکه کدی که نوشتن اگه بعد OutputStream.Write تابع Flush رو صدا می زد مشکل حل می شد.
با این حال این کلاس برای کار با فایل های بزرگ مشکل داره و مشکل چیزی نیست که تو گفتی.
مشکل ورودی تابع هست که از نوع byte و باید از نوع stream باشه.
فردا یه نگاهی می کنم تا این کلاس بر اساس Stream کار کنه و مشکل حل بشه.
سالار جان در SP 1 .NET framework دو تا overload به این متد اضافه شده بنا به تاپیک زیر
http://support.microsoft.com/kb/927128
و بنا به تاپیک زیر این overload جدید resum ساپورت میکنه
http://connect.microsoft.com/VisualS...dbackID=277370
من دقیقا یک فایل 700MB گذاشتم و وای ی ی ی ی ی ی ی
با remote به سرورم وصل شدم دیدم سرور ترکیده end task کردمش
من اطلاعی از این overload ها نداشتم.
بررسی می کنم.
با این حال همونطور که گفته بودم مشکل مربوط به خواندن فایل به باف در این کلاس بود که حلش کردم.
من این کلاس رو با فایل 70 MB تست کردم و یک مگ هم سربار نداشت.
این هم نمونه استفاده شده:
private DownloadState DoDownload(string fileName)
{
try
{
string fileHeaderName = Path.GetFileName(fileName).Replace(' ', '-');
ResumeDownload down = new ResumeDownload();
down.ClearResponseData();
DownloadState downState = down.ProcessDownload(fileName, fileHeaderName);
System.Diagnostics.Debug.WriteLine("\nDownloadStat e=" + downState.ToString());
if (downState == DownloadState.fsDownloadFinished)
{
// Do something here
}
return downState;
}
catch (ThreadAbortException)
{
// Nothing
}
سلام.
با تشکر،
من این پروسه رو برای فایلهای بزرگ تست کردم، خوب کار میکنه. اما بین 28 تا 38 درصد از پروسس CPU رو به ازای هر دانلود میگیره، همچنین خروجی اش رو با FlashGet تست کن، در بازه های زمانی بین 700 تا 1500 میلی ثانیه یکبار کانکشن اش ریست میشه (این رو با Casini که رو خود ویژوال استودیو 2005 هست تست کردم).
دوست عزیز SalarSoft
ممنون از پیگیری شما،
اگر وقت دارید از متد TransmitFile همراه با overload های جدید هم استفاده کنید، اینطور که به نظر میرسه باید بازدهی بهتری داشته باشه
فرق کلاس HttpRequest که شما استفاده کردین با HttpWebRequest در System.Net چیه؟
Salar جان ممنون
درستش کردم، مشکل server.mappath بود که استفاده نشده بود، جالب اینجا بود که هیچ پیغام خطایی نمی داد، ولی خب حل شد
من هم روی لوکال و هم production server تست کردم، مشکل cpu نداشت و پردازش کاملا عادی بود ، کانکشن لاست یا ریست در دو تا از پارت های دانلود بود با Flash get تست کردم.
که البته من حدس میزنم بخاطر وضعیت فعلی اینترنت ایران است (قطعی فیبرهای نوری در دریای مدیترانه)، چون وقتی پینگ هم می کنیم زیاد کانکشن لاست و timeout دارد، البته الان یک فایل را از سایت مایکروسافت هم دانلود کردم که اون هم کانکشن لاست داشت.
اینطور که به نظر می رسه مشکل حل شده، ولی اگر Salar لطف کنند و باز هم برای اطمینان این کانکشن لاست رو چک کنند بد نیست و اگر وقت کردند با متد TransmitFile هم کلاس رو بازنویسی کنند خیلی عالی میشه
ممنون از همگی
سلام
دیشب، درحال دانلود یک فایل 200 مگابایتی بودم حدود 10 مگابایت اون دانلودشده بود و pause کرده بودم (با Dap ) ولی بعد از ادامه دانلود dap دانلود رو ریست کرد و از اول دانلود کردش، حالا نمی دونم دلیلش چی بود ارتباطی به اون ریست شدن کانکشن که DelphiAssistant بهش اشاره کردند داره یا نه،
البته این رو هم اضافه کنم که سیستم دانلود من نیاز به لاگین کردن کاربران داره، یعنی بعد از اینکه چک شد که آیا کاربر Authenticated هست یا خیر متد مربوط به دانلود فایل رو اجرا می کنه و اگر نبود کاربر رو به صفحه ورود می فرسته، حالا فرض کنید کاربر یک بار در سایت لاگین کرده که فایل رو دانلود کنه بدون مشکل شروع به دانلود فایل میکنه آیا بعد از بستن مرورگر و حتی sign out باز هم می تونه بدون مشکل دانلود رو ادامه بده ؟ (آیا برنامه های دانلود منیجر کوکی ها رو بصورت جداگانه ذخیر می کنند ؟)
این رو خودم دیشب تست کردم با یک کاربر بصورت موقت لاگین و شروع به دانلود فایل کردم ، sign out کردم و الان (بعد از گذشت حدود 11 ساعت) دوباره دانلود فایل رو ادامه دادم فایل راحت دانلود میشه (این خیلی خوبه ولی آیا مطمئن و safe هست، آیا میشه اطمینان داشت که بعدا سیستم دانلود رو ریست نکنه و از اول مجبور نشیم دانلود کنیم ؟ )
آپدیت شد : جواب سئوال خودم، اولین باره چنین چیزی می بینم، زمانیکه با دانلود منیجر فایل رو دانلود می کنم حتی اگر در سایت لاگین نکرده باشم، دانلود منیجر بصورت خودکار با یوزری که قبلا برای شروع دانلود لاگین کرده بود بصورت خودکار لاگین می کنه ، حتی من با یک یوز دیگر هم لاگین کردم ولی اطلاعات ذخیره شده در دانلود منیجر تغییر نکرد و باز هم با همان یور در حال دانلود فایل است، خیلی خوبه ولی آیا میشه به این اعتماد کرد آیا safe است ؟
علت استفاده زیاد از CPU مربوط به ریست شدن کانکشن هست.اما بین 28 تا 38 درصد از پروسس CPU رو به ازای هر دانلود میگیره، همچنین خروجی اش رو با FlashGet تست کن، در بازه های زمانی بین 700 تا 1500 میلی ثانیه یکبار کانکشن اش ریست میشه
مشکل ریست شدن کانکشن در SP 1 حل شده و در نتیجه مشکلی با درصد بالای کار cpu نباید به وجود باید.
خیلی جالبه بدونید که ذاتا این overload ها قبلا (قبل از SP1) هم وجود داشتند و حالا فقط برای اونها تابع تعریف شده.در SP 1 .NET framework دو تا overload به این متد اضافه شده بنا به تاپیک زیر
برای مثال اگر می خواهید که از متد TransmitFile بدون نصب SP1 استفاده کنید از تابع کع نوشتم استفاده کنید:
void CallHiddenTransmitFile(HttpResponse objResponse,string fileName, long offset, long size)
{
Type tempType = objResponse.GetType();
FieldInfo tempInfo = tempType.GetField("_httpWriter", BindingFlags.NonPublic | BindingFlags.Instance);
HttpWriter _httpWriter = (HttpWriter)tempInfo.GetValue(objResponse);
tempType=tempInfo.FieldType;
tempInfo = tempType.GetField("_buffers", BindingFlags.NonPublic | BindingFlags.Instance);
ArrayList _buffers=(ArrayList)tempInfo.GetValue(_httpWriter) ;
tempType = _httpWriter.GetType();
tempInfo = tempType.GetField("_responseBufferingOn", BindingFlags.NonPublic | BindingFlags.Instance);
bool responseBufferingOn=(bool)tempInfo.GetValue(_httpW riter);
Type classType = tempType.Assembly.GetType("System.Web.HttpFileResp onseElement");
ConstructorInfo[] cinf = classType.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic);
object ret= cinf[2].Invoke(new object[]{fileName,offset,size,true,false,true});
_buffers.Add(ret);
if (!responseBufferingOn)
{
objResponse.Flush();
}
}
این تابع به عنوان overload در SP 1 عرضه شده که مسلما خیلی از سرور ها هنوز اون رو نصب نکردن پس می تونه برای استفاده یک گزینه خوب باشه.
این کلاس رو من با استفاده از overload جدید تابع transmitFile بازسازی کردم
تست شد و مشکل استفاده از CPU زیاد و یا ریست شدن کانکشن نداشت.
نکته: اگر .NET Framework SP1 رو نصب نکرده باشید با مشکلات مذبور مواجه خواهید شد.
برای سرورهایی که SP1 رو نصب کردن فایل ResumeDownload for SP1.zip رو دانلود کنید و برای سرورهایی که ندارن فایل ResumeDownload Not SP1.zip دانلود کنید.
تنها فرق این دو فایل در خط 332 هست که CallHiddenTransmitFile یا objResponse.TransmitFile فراخوانی شده.
نحوه استفاده فرق نکرده ولی دوباره می نویسم:
public static void DownloadFile(string fileName)
{
try
{
string fileHeaderName = System.IO.Path.GetFileName(fileName).Replace(' ', '-');
SalarSoft.Utility.ResumeDownload down = new SalarSoft.Utility.ResumeDownload();
// Start downloading
SalarSoft.Utility.DownloadState state = down.ProcessDownload(fileName, fileHeaderName);
if (state == SalarSoft.Utility.DownloadState.fsDownloadFinished )
{
// Your code
}
}
catch (System.Threading.ThreadAbortException)
{
// Nothing
}
}
* مدیر بخش یا سایت اگر امکانش هست این رو به عنوان اعلان بزنن شاید مشکل خیلی ها باشه.
خیلی ممنون ، لطف کردید
من نیاز به یک سیستم دانلود با بازدهی خوب و البته کاملا stable دارم ، نظر شما کدامیک است، متد قبلی یا این متد جدید TransmitFile ؟
راستی فراموش کردم، لطفا حجم فایل هم به header بفرستید چون زمان دانلود حجم فایل رو unknown شناسایی می کنه
من از این روش استفاده کردم منتها با ویبی کدهام مشکل نداره منتها مقدار state در تابع DownloadFile صفر بر می گرده چون در کلاس ResumeDownload
از خطوط زیر پرش می کنه و دیگه ادامه نمی ده
If Not (objRequest.HttpMethod.Equals(HTTP_METHOD_GET) OrElse objRequest.HttpMethod.Equals(HTTP_METHOD_HEAD)) Then
objResponse.StatusCode = 501 ' Not implemented
ElseIf Not objFile.Exists Then
شرمنده خیلی ابتداییه
میشه توضیح بدین اصلا چرا از این روش استفاده میشه (لطفا سطح پایین بگین تا من بفهمم ) . فکر کنم برای فایل با حجم بزرگ کارایی داره
این موضوع چاره داره
چارشم چیزی نیست جز نوشتن یه کلاس جدید
اگه یکی از دوستان بشینه سره فرصت با بررسی دقیق کار این سیستم یه کلاس رو تهیه کنه مشکل حل میشه .
موفق باشید
نسخه جدید این کلاس همراه با قابلیت کنترل سرعت دانلود و توضیحات نحوه استفاده رو از اینجا دریافت کنید:
http://blog.salarcode.com/2012/02/as...wnloading.html
سلام اقای SalarSoft عزیز
در مورد قسمت ResumableDownload.ashx چون یک فایل در پروژه هست .
نمی توانستید اونم در کلاس بزارید که دیگه نیازی به فراخونی نباشه