PDA

View Full Version : سوال: file stream



qasemf
دوشنبه 10 شهریور 1399, 01:04 صبح
سلام یه اپ نوشتم برای اتقال فایل ...زمانی که برای اولین بار مثلا چن تا فیلم رو کپی میکنم و past میکنم برنامه درست عمل میکنه اما همین که دوباره یه انتقال فایل دیگه داشته باشم یعنی به صورت همزمان همون فایل ها رو دوباره میخوام کپی کنم تو یه پوشه دیگه برنامه تقریبا متوقف میشه یعنی میگه این فایل ها قبل باز شدن و شما اجازه دسترسی مجدد ندارین به اونها ... متوجه میشم که داستان چیه اما نمیدونم چطور پیادش کنم

daniyaltjm
دوشنبه 10 شهریور 1399, 10:11 صبح
فکر کنم مشکل از backgroundWorker باشه

qasemf
دوشنبه 10 شهریور 1399, 16:38 عصر
فکر کنم مشکل از backgroundWorker باشه

چه مشکلی؟ میشه توضیح بدین ؟

daniyaltjm
دوشنبه 10 شهریور 1399, 19:48 عصر
چه مشکلی؟ میشه توضیح بدین ؟

کد ها رو تست کردم و مشکلی نداره و درست کار میکنه

qasemf
دوشنبه 10 شهریور 1399, 23:42 عصر
کد ها درستن برنامه به خوبی اجرا میشه یه انتقال فایل انجام میدم و به صورت همزمان یه انتقال فایل دیگه که میخوام انجام بدم برنامه هنگ میکنه بعد پیغام میده که دسترسی به فایل ندارید چون اون فایل تو یه پروسه دیگه در حال پردازش هست یه همچین چیزی میگه ...شما دقت کن الان توی ویندوز هر تعدادی که بخوای میتونی به صورت همزمان فایل ها تو به چن تا مسیر مختلف کپی کنی و ویندوز قفل نمیکنه که اما این برنامه ....

the king
سه شنبه 11 شهریور 1399, 00:00 صبح
سلام یه اپ نوشتم برای اتقال فایل ...زمانی که برای اولین بار مثلا چن تا فیلم رو کپی میکنم و past میکنم برنامه درست عمل میکنه اما همین که دوباره یه انتقال فایل دیگه داشته باشم یعنی به صورت همزمان همون فایل ها رو دوباره میخوام کپی کنم تو یه پوشه دیگه برنامه تقریبا متوقف میشه یعنی میگه این فایل ها قبل باز شدن و شما اجازه دسترسی مجدد ندارین به اونها ... متوجه میشم که داستان چیه اما نمیدونم چطور پیادش کنم

شما یک کار اصولی در کدتون انجام داده اید و فایل ها رو با using باز کرده اید، استفاده از using شما رو از Close کردن بی نیاز می کنه، لذا اون ()Close ها اضافی هستند، می توانید از کد حذف شان کنید. حتی اگر وسط کد ها خطایی رخ بده یا return ای انجام بدید از بدنه using که خارج بشه بصورت خودکار Close صورت می گیره و لازم نیست نگران Close شدنش باشید.

شما فایل رو با File.Open باز کرده اید اما دسترسی اشتراکی به فایل رو مشخص نکرده اید. به همین جهت از دسترسی اشتراکی پیشفرض استفاده شده که اجازه باز شدن همزمان فایل در روتین دیگری رو نمیده. یا از OpenRead استفاده کنید یا صریحا دسترسی اشتراکی رو مشخص کنید،
هر دو تا کد زیر عینا یک سطح دسترسی مشابه دارن. صرفا OpenRead متد خلاصه تری است وگرنه اینکه از کدوم شون استفاده کنید تفاوتی در نتیجه نداره.

using (var fsin = File.OpenRead(source))
{



using (var fsin = File.Open(source, FileMode.Open, FileAccess.Read, FileShare.Read))
{

daniyaltjm
سه شنبه 11 شهریور 1399, 01:18 صبح
شما یک کار اصولی در کدتون انجام داده اید و فایل ها رو با using باز کرده اید، استفاده از using شما رو از Close کردن بی نیاز می کنه، لذا اون ()Close ها اضافی هستند، می توانید از کد حذف شان کنید. حتی اگر وسط کد ها خطایی رخ بده یا return ای انجام بدید از بدنه using که خارج بشه بصورت خودکار Close صورت می گیره و لازم نیست نگران Close شدنش باشید.

شما فایل رو با File.Open باز کرده اید اما دسترسی اشتراکی به فایل رو مشخص نکرده اید. به همین جهت از دسترسی اشتراکی پیشفرض استفاده شده که اجازه باز شدن همزمان فایل در روتین دیگری رو نمیده. یا از OpenRead استفاده کنید یا صریحا دسترسی اشتراکی رو مشخص کنید،
هر دو تا کد زیر عینا یک سطح دسترسی مشابه دارن. صرفا OpenRead متد خلاصه تری است وگرنه اینکه از کدوم شون استفاده کنید تفاوتی در نتیجه نداره.

using (var fsin = File.OpenRead(source))
{



using (var fsin = File.Open(source, FileMode.Open, FileAccess.Read, FileShare.Read))
{


سلام The king (https://barnamenevis.org/member.php?259237-the-king) برای کپی کردن فایل توی یک زمان بهتر نیست از Thered استفاده بشه؟!:متفکر:

qasemf
سه شنبه 11 شهریور 1399, 01:26 صبح
اقا مشکل حل شد واقعا ممنونم ساده بود اما واقعا کاربردی بود چقدر لذت بخشه که اینقدر رسا توضیح دادین و به جواب رسیدم سپاس فراوان

qasemf
سه شنبه 11 شهریور 1399, 01:35 صبح
به صورت همزمان ۴ تا انقال فایل انجام دادم و برا جالبه که همشون باهم به پایان رسیدن چون هر کدوم با فاصله زمانی ۱۰ ثانیه شروع شدن ولی تو یه تایم انتقال ها به پایان رسیدن برنامه هنگ نکرد حالا به قول دوستمون با thread بهتره یا به این شکل؟

the king
سه شنبه 11 شهریور 1399, 01:48 صبح
سلام The king (https://barnamenevis.org/member.php?259237-the-king) برای کپی کردن فایل توی یک زمان بهتر نیست از Thered استفاده بشه؟!:متفکر:

هم آره و هم نه. بستگی به شرایط داره. در برنامه هایی مثل FastCopy این شرایط در نظر گرفته میشه. باید در نظر بگیریم که می توانیم به یک هارد دیسک چند درخواست همزمان بدیم، اما نمیتونه همزمان به اون درخواست ها پاسخ بده، وقتی داره به یک درخواست پاسخ میده سایر درخواست ها منتظر میمونند.
برای همین چند تا شرایط متفاوت هست که همدیگه رو نقض می کنند.

وقتی مبدا کپی یک فایل یکسان باشه، احتمالش هست که وقتی فایل با Thread اول کپی شد، در بافر سیستم فایل یا هارد دیسک باقی بمونه و موقع کپی کردن در Thread دوم بخاطر وجودش در بافر نیازی به مراجعه به دیسک نباشه و سریعتر خونده بشه، پس دو تا Thread بودن به خوندن سریعتر فایل مبدا در Thread دوم کمک می کنه و حداقل در خوندن دو تا Thread همزمان بهتر از دو تا Thread پشت سر هم اجرا میشن.

اما یک مشکلی در مورد هارد دیسک ها هست، دیسک جایی رو میخونه یا می نویسه که هد ها در اون موقعیت قرار داره، نمیتونه همزمان از چند جا بخونه و بنویسه. برای همین هر چقدر درخواست های همزمان رو افزایش بدهید به همون اندازه تعداد جابجایی های هد روی دیسک افزایش پیدا می کنه که خودش در خوندن و نوشتن تاخیر ایجاد می کنه. ممکنه با افزایش تعداد نخ بجای اینکه نتیجه مثبتی بگیرید عملا هم در پاسخگویی سیستم عامل به سایر برنامه ها مشکل ایجاد کنید و هم استهلاک هارد دیسک رو افزایش بدهید و اگر سایر برنامه ها هم هارد دیسک رو درگیر کنند بجای افزایش سرعت کاهش سرعت داشته باشید.

یک مساله دیگه هم هست، اگر مقصد Thread اول و دوم دیسک های متفاوتی باشند، نوشتن همزمان روی دو دیسک متفاوت مزاحمتی برای همدیگه نداره، پس اجرای هم زمان شون در دو نخ مجزا قطعا سرعت نوشتن فایل ها رو افزایش میده.

در برنامه هایی مثل FastCopy بررسی میشه که آیا مبدا و مقصد دیسک های یکسانی هستند یا نه، اگر یکسان باشند صرفا از یک Thread استفاده میشه و پروسه های مشابه منتظر تمام شدن اولی می مانند، چون دیسک نمیتونه همزمان به چند درخواست پاسخ بده. ولی اگر دیسک های متفاوتی باشند، در پروسه های متفاوت (Thread های متفاوتی) همزمان اجرا میشن.
البته مزیت و عیب هر روشی رو صرفا باید در اجرا بسنجید. گاهی اون چیزی که روی کاغذ درست به نظر میاد با نتیجه تجربی مطابقت نداره.

daniyaltjm
سه شنبه 11 شهریور 1399, 07:29 صبح
هم آره و هم نه. بستگی به شرایط داره. در برنامه هایی مثل FastCopy این شرایط در نظر گرفته میشه. باید در نظر بگیریم که می توانیم به یک هارد دیسک چند درخواست همزمان بدیم، اما نمیتونه همزمان به اون درخواست ها پاسخ بده، وقتی داره به یک درخواست پاسخ میده سایر درخواست ها منتظر میمونند.
برای همین چند تا شرایط متفاوت هست که همدیگه رو نقض می کنند.

وقتی مبدا کپی یک فایل یکسان باشه، احتمالش هست که وقتی فایل با Thread اول کپی شد، در بافر سیستم فایل یا هارد دیسک باقی بمونه و موقع کپی کردن در Thread دوم بخاطر وجودش در بافر نیازی به مراجعه به دیسک نباشه و سریعتر خونده بشه، پس دو تا Thread بودن به خوندن سریعتر فایل مبدا در Thread دوم کمک می کنه و حداقل در خوندن دو تا Thread همزمان بهتر از دو تا Thread پشت سر هم اجرا میشن.

اما یک مشکلی در مورد هارد دیسک ها هست، دیسک جایی رو میخونه یا می نویسه که هد ها در اون موقعیت قرار داره، نمیتونه همزمان از چند جا بخونه و بنویسه. برای همین هر چقدر درخواست های همزمان رو افزایش بدهید به همون اندازه تعداد جابجایی های هد روی دیسک افزایش پیدا می کنه که خودش در خوندن و نوشتن تاخیر ایجاد می کنه. ممکنه با افزایش تعداد نخ بجای اینکه نتیجه مثبتی بگیرید عملا هم در پاسخگویی سیستم عامل به سایر برنامه ها مشکل ایجاد کنید و هم استهلاک هارد دیسک رو افزایش بدهید و اگر سایر برنامه ها هم هارد دیسک رو درگیر کنند بجای افزایش سرعت کاهش سرعت داشته باشید.

یک مساله دیگه هم هست، اگر مقصد Thread اول و دوم دیسک های متفاوتی باشند، نوشتن همزمان روی دو دیسک متفاوت مزاحمتی برای همدیگه نداره، پس اجرای هم زمان شون در دو نخ مجزا قطعا سرعت نوشتن فایل ها رو افزایش میده.

در برنامه هایی مثل FastCopy بررسی میشه که آیا مبدا و مقصد دیسک های یکسانی هستند یا نه، اگر یکسان باشند صرفا از یک Thread استفاده میشه و پروسه های مشابه منتظر تمام شدن اولی می مانند، چون دیسک نمیتونه همزمان به چند درخواست پاسخ بده. ولی اگر دیسک های متفاوتی باشند، در پروسه های متفاوت (Thread های متفاوتی) همزمان اجرا میشن.
البته مزیت و عیب هر روشی رو صرفا باید در اجرا بسنجید. گاهی اون چیزی که روی کاغذ درست به نظر میاد با نتیجه تجربی مطابقت نداره.

بسیار عالی:تشویق:

حالا سوالی که پیش میاد برای کد بالا اینه که دوستمون گفته انتقال ها هم زمان انجام شده ولی ظاهرا از یک backgroundWorker استفاده کرده یا من اشتباه می کنم! دراین صورت باید کار انتقال اولی انجام بشه بعد دومی... مگر اینکه از چند تا backgroundWorker استفاده کرده باشه!:متفکر:

qasemf
سه شنبه 11 شهریور 1399, 18:48 عصر
من با backgroundworker کار کردم دیشب انتقال فایل ها رو فقط داخل هارد دیسک تست کردم الان که خواستم فایل هارو داخل فلش انتقال بدم برنامه هنگ کرد دوتا انتقال همزمان اجرا شد اما سومی رو که زدم برنامه هنگ کرد حالا راهکار چیه؟ از thread استفاده کنم؟ البته باهاش زیاد اشنایی ندارم چند تا thread باید بزارم

the king
سه شنبه 11 شهریور 1399, 22:26 عصر
من با backgroundworker کار کردم دیشب انتقال فایل ها رو فقط داخل هارد دیسک تست کردم الان که خواستم فایل هارو داخل فلش انتقال بدم برنامه هنگ کرد دوتا انتقال همزمان اجرا شد اما سومی رو که زدم برنامه هنگ کرد حالا راهکار چیه؟ از thread استفاده کنم؟ البته باهاش زیاد اشنایی ندارم چند تا thread باید بزارم

BackgroundWorker و Thread و Task هر سه شون یک کار رو انجام میدن، بصورت غیر مستقیم یا مستقیم نخ می سازند.
اما استفاده از BackgroundWorker در اینجور موارد که شما ممکنه روال رو وسط کار کنسل کنید یا در حین روال در فرم چیزی رو نمایش بدهید، ساده تر ئه.
پیاده سازی اش با Thread صرفا کد نویسی بیشتری می طلبه. CancellationPending برای بررسی کنسل شدن روال یا ReportProgress که وقتی میخواهید با نخ اداره کننده فرم ارتباط برقرار کنید، در BackgroundWorker بصورت آماده هست و لازم نیست چیزی رو Invoke کنید یا فیلدی رو به اشتراک بگذارید.
همه اینکار ها رو با Thread هم می توانید انجام بدهید اما با کد نویسی بیشتری، مزیت خاصی هم نداره.

با توجه به شرایط نرم افزاری و سخت افزاری تعداد Thread های مناسب فرق می کنه، اما اینکه دو تا نخ همزمان و بدون مشکل اجرا میشن نشون میده که روال کلی که داشتید درسته.
ممکنه در ساختن BackgroundWorker سوم در جایی اشتباه کوچکی کرده باشید که تداخل ایجاد میکنه یا یک ویرایشی رو از قلم انداخته باشید.

دو حالت هنگ کردن هست، موقتی و دائمی. حالت اولی اینه که درخواست های نخ سوم چون مجال اجرا شدن پیدا نمی کنند، خیلی معطل میشن، ولی وقتی فرصت اجرا شدن پیدا کردن بدون مشکل کپی انجام میشه. اگر چنین حالتی پیش اومد، ممکنه ظرفیت پاسخگویی در همین حد باشه، نمیتوانیم توقع داشته باشیم که به هر تعدادی نخ بسازیم و هیچکدوم تاخیر در اجرا نداشته باشند.
اما اگر هنگ کردن دائمی است و خلاصی نداره، طبیعی نیست و حتما یکجای کار ایراد داره.

qasemf
چهارشنبه 12 شهریور 1399, 05:23 صبح
صحیح... امروز دوباره چک کردم و دیدم هنگ موقتی داره و دایمی نیست که به قول شما طبیعی به نظر می رسه ..مرسی از اینکه وقتتون رو بهم دادین سپاس...