PDA

View Full Version : اعمال کنترل بر روی زمان اجرای یک قطعه کد



Pari_Programmer
سه شنبه 15 شهریور 1390, 18:03 عصر
سلام دوستان

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

کسی میتونه کمک کنه در این زمینه؟
با try-catch میشه این کار رو کرد؟

saha_h2001
سه شنبه 15 شهریور 1390, 18:41 عصر
سلام دوست من این کارو میشه با استفاده از مباحث ترد(thread) تو سی شارپ انجام دهید و مدت زمان اعمال یا اجرای یک عمل را کنترل کنید تو اینترنت پیگیر شوید ضمنا با try, catch نمیشه (با استفتده از دریافت زمان سیستم و بررسی زمان مورد نظر هم این کار امکان پذیره)

محسن شامحمدی
سه شنبه 15 شهریور 1390, 19:11 عصر
ضمن تاببد حرف های saha_h2001 عزیز
من واستون یک نمونه با ترد درست کردم.امیدوارم خوشتون بیاد
روش کار: یه دونه ترد می سازیم و داخل اون تابع مورد نظر رو اجرا می کنیم.حالا از بیرون ترد هر لحظه که بخوایم مثلا 5 ثانیه بعد از اجرای ترد چک می کنیم که کار ترد تموم شد یا نه.
پ.ن: سازگار با دات نت 3.5
بدون سربار اضافی روی برنامه.

mehdi.mousavi
سه شنبه 15 شهریور 1390, 19:36 عصر
سلام دوستان من یه برنامه نوشتم که باید بر روی زمان اجرای یک قسمت از اون محدودیت بزارم. به عبارت دیگه میخوام یه تابع رو فراخوانی کنم که اگه مدت زمان اجرای اون بیش از حد مورد نظر طول بکشه، باید متوقف بشه و بقیه دستورات برنامه اجرا بشن. در ضمن این رو هم بگم که من به دستورات داخل تابع مذکور دسترسی ندارم و نمیتونم داخل اون رو تغییر بدم. پس باید در قسمتی که تابع فراخوانی میشه این کنترل انجام بشه. کسی میتونه کمک کنه در این زمینه؟ با try-catch میشه این کار رو کرد؟

سلام.
شما می تونید با استفاده از TPL، بدین شکل عمل کنید:


CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;
Task task = Task.Factory.StartNew(() =>
{
//Call your function here...
Thread.Sleep(10000);
token.ThrowIfCancellationRequested();
});

if (!task.Wait(3000, token))
cts.Cancel();


اونجاییکه Sleep(10000) رو گذاشتم، باید تابع مورد نظرتون رو صدا بزنید. اینجا، delegate ای که تعریف کرده ام بلافاصله Call میشه، و اونو از قصد 10 ثانیه به حالت Sleep میبرم. سپس، به Task سه ثانیه فرصت میدم کارش تموم بشه، که اگه نشه، درخواست Cancel رو روی Token مربوطه Fire می کنم. اما این کد، وقتی خوبه که شما به Source تابع مورد نظر دسترسی داشته باشید و بتونید در Interval های زمانی مشخصی بررسی کنید که آیا درخواست Cancel اون Task ست شده یا خیر. چون فرمودید به Source تابع دسترسی ندارید، بهترین روشی که در حال حاضر به ذهنم میرسه (و احتمالا کمترین Side Effect رو روی Application شما داشته باشه)، این هستش که یک Application Domain جداگانه در برنامه خودتون اجرا کنید، و تابع مزبور رو بصورت Sand Box (و ایزوله از بقیه Application) اجرا کنید. برای اینکار، می تونید بدین شکل عمل کنید:

AppDomainSetup appDomainSetup = new AppDomainSetup
{
ApplicationBase = System.Environment.CurrentDirectory,
DisallowBindingRedirects = false,
DisallowCodeDownload = true,
ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.Configura tionFile
};

string assemblyName = Assembly.GetEntryAssembly().FullName;

AppDomain newAppDomain = AppDomain.CreateDomain("New App Domain", null, appDomainSetup);
MySandBox sandBox = (MySandBox)newAppDomain.CreateInstanceAndUnwrap(as semblyName, typeof(MySandBox).FullName);
sandBox.Run(Thread.GetDomain().FriendlyName);

System.Threading.Thread.Sleep(2000);
AppDomain.Unload(newAppDomain);

public class MySandBox : MarshalByRefObject
{
public void Run(string callingDomainName)
{
Task.Factory.StartNew(() =>
{
System.Threading.Thread.Sleep(10000);
});
}
}


اینجا، ابتدا من یک App Domain جدید ایجاد می کنم و سپس، متود Run رو از کلاس MySandBox رو در App Domain جدید، اجرا می کنم. الان هر خرابکاری ای توی این متود ایجاد بشه، مطمئنم که بقیه Appی من صدمه نخواهد دید. در نهایت، هر جا که لازم باشه، App Domain ایجاد شده رو با متود Unload از بین میبرم. (اما با اینحال دقت کنید که اگر تابع مورد نظرتون قراره با Kernel در ارتباط باشه، بازهم ممکنه Driver های مورد نظر رو در وضعیت Unstable ای قرار بده).

موفق باشید.

linux
سه شنبه 15 شهریور 1390, 21:07 عصر
سلام.
شما می تونید با استفاده از TPL، بدین شکل عمل کنید:


موفق باشید.
عمرا اگر بجز خودت و 2-3 نفر دیگر سر در آورده باشند که چی گفتی. باور نمی کنی بپرس منظور از sandbox چی هست! همه یاد ساحل می افتند.
این تو دات نت 4 معرفی شد؟ درست هست. تا حالا در پرژه های تجاری از این استفاده کردید؟ در کدام قسمت از برنامه ؟

mehdi.mousavi
سه شنبه 15 شهریور 1390, 21:54 عصر
عمرا اگر بجز خودت و 2-3 نفر دیگر سر در آورده باشند که چی گفتی. باور نمی کنی بپرس منظور از sandbox چی هست! همه یاد ساحل می افتند.
این تو دات نت 4 معرفی شد؟ درست هست. تا حالا در پرژه های تجاری از این استفاده کردید؟ در کدام قسمت از برنامه ؟

بله. Task ها در .NET Framework 4.0 معرفی شدند. من در یکی دو پروژه از Task ها استفاده کرده ام که یکی از اونها، پردازش فایل XML حجیمی بود که با استفاده از Task ها، روی CPU های 4 هسته ای، سرعت پردازش همون فایل 4 برابر شد (در حقیقت Task های مورد نظر به درستی روی Core های موجود توزیع شد). اما در مورد Sandbox ... خیر! من در هیچ پروژه ای از این روش استفاده نکرده ام، اما تنها روشی که به نظرم اجرای یک تابع رو می تونست در .NET ایزوله کنه، همین استفاده از Application Domain ها بود. تابعی که source اش رو نداریم (و احتمالا نمیدونیم چی کار میکنه و ...)...

موفق باشید.


پاورقی: چون حدس میزدم خیلی از بچه ها ندونن Sandbox یعنی چی، اون عبارت "و ایزوله از بقیه Application" رو در پرانتز نوشتم :)

gwbasic
چهارشنبه 16 شهریور 1390, 09:24 صبح
ضمن تشکر از پاسخ آقای موسوی در مورد پست Linux باید اینو بگم که مطمئنا کسی که سوال می کنه یا کسی که جواب سوال دیگری رو می بینه شاید همه مطالب رو متوجه نشه چون در یک پست که نمی شه همه چی رو توضیح داد و همون ذکر عناوین هم می تونه مشکل ساز باشه مثلا AppDomain و همون SandBox که منم فرصت نکردم بررسی کنم ولی خوب کسی که دنبال جوابی هست می تونه اینا رو بررسی کنه و به نتیجه بررسه
بذار یه مثال بزنم من یه زمانی می خواستم Form Designer بسازم خوب کار خیلی مشکلی هستش نمی تونستم توقع داشته باشم که کسی بیاد بهم توضیح بده اما یکی از دوستام گفت که توی .net هست کافیه DesignerHost رو جستجو کنی که منم رفتم دنبالش و اونو پیدا کردم البته دیدم که چه امکانات دیگه ای وجود داره ... . همون یک کلمه خیلی به من کمک کرد
بنظرم توی برنامه نویسی حتی عنوان کردن یک تکنولوژی یا حتی یه مبحث می تونه راه گشا باشه چون همه کس همه چیزو نمی دونه

linux
چهارشنبه 16 شهریور 1390, 11:58 صبح
ضمن تشکر از پاسخ آقای موسوی در مورد پست Linux باید اینو بگم که مطمئنا کسی که سوال می کنه یا کسی که جواب سوال دیگری رو می بینه شاید همه مطالب رو متوجه نشه چون در یک پست که نمی شه همه چی رو توضیح داد و همون ذکر عناوین هم می تونه مشکل ساز باشه مثلا AppDomain و همون SandBox که منم فرصت نکردم بررسی کنم ولی خوب کسی که دنبال جوابی هست می تونه اینا رو بررسی کنه و به نتیجه بررسه
بذار یه مثال بزنم من یه زمانی می خواستم Form Designer بسازم خوب کار خیلی مشکلی هستش نمی تونستم توقع داشته باشم که کسی بیاد بهم توضیح بده اما یکی از دوستام گفت که توی .net هست کافیه DesignerHost رو جستجو کنی که منم رفتم دنبالش و اونو پیدا کردم البته دیدم که چه امکانات دیگه ای وجود داره ... . همون یک کلمه خیلی به من کمک کرد
بنظرم توی برنامه نویسی حتی عنوان کردن یک تکنولوژی یا حتی یه مبحث می تونه راه گشا باشه چون همه کس همه چیزو نمی دونه

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

Pari_Programmer
چهارشنبه 16 شهریور 1390, 15:31 عصر
با تشکر از همه دوستان

توضیحاتتون خیلی مفید بود. ممنونم.
فقط خواهش میکنم با هم محترمانه برخورد کنیم.
Linux عزیز متاسفانه بر خلاف اسمی که انتخاب کردید، شیوه برخورد مناسبی با دوستانتون ندارید. شاید بگید چه ربطی داره. الان براتون توضیح میدم:
سیستم عامل linux با همه برتری ها و قدرتی که نسبت به سایر سیستم عامل ها داره (البته نه در همه موارد. که اون هم جای بحث داره)، با سایر سیستم عاملها و به عبارت دیگه با دوستان یا رقیب هاش برخورد نامناسبی نداره. بلکه سعی می کنه به آرومی و با متانت با رقیبهاش برخورد کنه. با قدرتش خودش رو به دیگران ثابت میکنه و به همه میفهمونه که یه چیزی بیشتر از اونها داره. اینجوری خودش رو قابل احترام میکنه و شایسته احترام.
اما در مقابلش سیستم عامل ویندوز قرار داره که متاسفانه برخورد مناسبی با رقبا نداره. این مسئله باعث شده که حتی کاربران معمولی (که فقط user firendly بودن سیستم عامل براشون مهمه) علیرغم برتر بودن ویندوز در کاربردهای معمولی، اون رو قبول نداشته باشن و هیچ کس از ویندوز خوشش نیاد.
البته منظور من از linux و ویندوز در اینجا شرکت microsoft و افراد درگیر در پروژه های متن باز بود.
امیدورام منظورم رو خوب رسونده باشم. با برخوردهای نیش دار و کنایه آمیز نه میتونید خودتون رو به دیگران تحمیل کنید و نه اینکه شایسته احترام میشید.

"افتادگی آموز اگر طالب علمی"

باز هم از همه دوستان ممنونم.
یا حق

linux
چهارشنبه 16 شهریور 1390, 17:57 عصر
با تشکر از همه دوستان
"افتادگی آموز اگر طالب علمی"
باز هم از همه دوستان ممنونم.
یا حق
عمرا اگر مصرع دوم این شعر را حفظ باشی!
سوالی بود از آقای موسوی که من جوابم را گرفتم شما هم بهتر بود به جای حاشیه پردازی و آف تاپیک از این نکته استفاده می کردید که task ها در .نت 4 چیز بدرد بخوری هست و بجای تعریف از لینوکس و بد گفتن از ویندوز توی msdn نگاهی به System.Threadings.Tasks می انداختید و در مورد برنامه نویسی موازی تحقیق می کردید و سعی می کردید در یکی از پروژه هاتون از این امکان استفاده کنید. نه من نه بقیه دوستان قدیمی که اینجا هستند دنبال رقابت و این چیزها نیستند.
"آب نخورد زمینی که بلند هست".

Pari_Programmer
چهارشنبه 16 شهریور 1390, 18:28 عصر
linux عزیز
من مجددا شما رو دعوت به ادب و تربیت می کنم
شما هم به جای اینکه تن شاعر رو توی گور بلرزونی یه سرچ توی اینترنت می کردی و مصرع دوم رو درست می گفتی:
"هرگز نخورد آب زمینی که بلند است"
به نظر من اینجا با وجودی که محیطی صمیمی و دوستانه برای علاقه مندان به برنامه نویسی است، احترام افراد باید حفظ شده و دوستان محترمانه با هم صحبت کنن. این مسئله که شما و آقای موسوی دوست قدیمی هستین خیلی خوب و قابل احترامه اما لطفا از این به بعد جنبه ادب و تربیت رو هم در مکاتباتتون رعایت کنید.

اما برم سر اصل مطلب.
من متاسفانه خیلی از چگونگی پیاده سازی threadها در C# اطلاع ندارم و باز هم متاسفانه کارم خیلی force major هستش.

آقای شاه محمدی عزیز دست شما درد نکنه. کد ساده و خوبی بود اما کدی که من دارم روش کار میکنم win32 هستش و نتونستم بفهمم که این کد شما رو چه طور توی کد خودم اضافه کنم. میشه یه راهنمایی بکنید؟

آقای موسوی عزیز
از شما هم ممنونم بابت راهنماییتون. اما من به دلیل ناآشنایی با C# نتونستم بفهمم کد شما رو چه جور در کد خودم استفاده کنم. البته این نکته رو هم بگم که این کد رو من ننوشتم. برای یه کاربردی دیدم این برنامه خیلی خوب کار میکنه، فقط یه چندتا مشکل داره که یکیش این موضوعیه که از شما پرسیدم.
این خط رو که توی کدم میزارم گیر ارور میده:
ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.Configura tionFile;
گویا باید یه چیزی به این دستور اضافه بشه. اما هر چی گشتم دیدم همین دستور رو دیگران هم به همین شکل استفاده میکنن. اشکال کار کجاست نمیدونم.
میشه راهنماییم کنید؟

با تشکر

linux
چهارشنبه 16 شهریور 1390, 19:11 عصر
linux عزیز
من مجددا شما رو دعوت به ادب و تربیت می کنم
شما هم به جای اینکه تن شاعر رو توی گور بلرزونی یه سرچ توی اینترنت می کردی و مصرع دوم رو درست می گفتی:
"هرگز نخورد آب زمینی که بلند است"
با تشکر
مهم معنی بود و اینکه شما هم نمی دونستید رفتید سرچ کردید! نه اینکه فارسی جستجو نداره شما سرچ می کنید.
اون قسمت از کد که کلاس sandbox هست در یک کلاس بنویسد با افزدون کلاس جدید به پروژه .
کد مربوط به appdomain را هم در بدنه اصلی برنامه بنویسید.
و System.Reflection به قسمت using ها اضافه کنید و فاصله اضافی بین a , t در کلمه configuration را حذف کنید.
سعدی خدا بیامرزهم آدم با جنبه ای بوده قطعا کل شعر را هم سر و ته می گفتم نه تنها تو گور نمیلرزید بلکه از شادی یه قری هم می داد.

Pari_Programmer
چهارشنبه 16 شهریور 1390, 20:42 عصر
من متاسفانه به این دقت نکرده بودم که شما فرمودین Taskها در .NET framework 4 معرفی شدن. متاسفانه من NET 3.5 دارم استفاده می کنم. میخواستم بدونم آیا راهکاری برای این قضیه دارید؟
این پروژه که من میخوام تغییرش بدم با NET 3.5 نوشته شده و من برای استفاده از NET 4 در این پروژه دوتا مشکل دارم: اولا اینکه من Visual Studio 2010 ندارم. دوم این که در صورت انتقال کد به NET 4 ممکنه بعضی از توابع کار نکنن.
آیا راهکاری هست که بدون مهاجرت به NET 4 بتونم این قضیه رو حل کنم؟

باز هم از همکاری دوستان ممنونم.

محسن شامحمدی
پنج شنبه 17 شهریور 1390, 11:58 صبح
من متاسفانه به این دقت نکرده بودم که شما فرمودین Taskها در .NET framework 4 معرفی شدن. متاسفانه من NET 3.5 دارم استفاده می کنم. میخواستم بدونم آیا راهکاری برای این قضیه دارید؟
این پروژه که من میخوام تغییرش بدم با NET 3.5 نوشته شده و من برای استفاده از NET 4 در این پروژه دوتا مشکل دارم: اولا اینکه من Visual Studio 2010 ندارم. دوم این که در صورت انتقال کد به NET 4 ممکنه بعضی از توابع کار نکنن.
آیا راهکاری هست که بدون مهاجرت به NET 4 بتونم این قضیه رو حل کنم؟

باز هم از همکاری دوستان ممنونم.

اگر به پست من دقت می کردید می دیدید که بنده این نکته رو نوشتم که این کد توی حتی دات نت 2 هم کار می کنه.البته قبول دارم که به Task هایی که توی دات نت 4 هستن نمی رسه ولی به هر حال برای کار شما به خوبی و به طور قابل قبولی جواب می ده.


آقای شاه محمدی عزیز دست شما درد نکنه. کد ساده و خوبی بود اما کدی که من دارم روش کار میکنم win32 هستش و نتونستم بفهمم که این کد شما رو چه طور توی کد خودم اضافه کنم. میشه یه راهنمایی بکنید؟
کد من که خیلی ساده بود.نمی دونم کجاشو متوجه نشدید.
ضمنا یعنی چی برنامتون Win32 هستش؟
اصلا برنامه های تولیدی سی شارپ همگیشون Managed هستن و برنامه های Win32 نداره!
شاید منظورتون اینه که برنامتون تحت کنسوله؟!! اگر اونطوری هم باشه بازم کد ایجاد ترد فرقی نداره و به جای تایمر هم می تونید از ThreadTimer استفاده کنید.
اگر راهنمایی بنده فایده نداشت بگید با ThreadTimer هم واستون یدونه نمونه می دم.

Pari_Programmer
جمعه 18 شهریور 1390, 13:21 عصر
فرض کن من یک کلاس دارم به اسم myclass که داخل اون هم یک سری توابع معرفی و استفاده میشن.
من تا حالال با تردها کار نکردم. چه جوری باید یک thread رو توی این کلاس ایجاد کنم و بعد ازش توی یکی از کلاسهام استفاده کنم.
برنامه هم تحت کنسوله. یعنی فرمی ندارم که بخوام موقع ایجاد فرم ترد رو ایجاد کنم.
چی کار باید بکنم؟

محسن شامحمدی
جمعه 18 شهریور 1390, 17:56 عصر
فرض کن من یک کلاس دارم به اسم myclass که داخل اون هم یک سری توابع معرفی و استفاده میشن.
من تا حالال با تردها کار نکردم. چه جوری باید یک thread رو توی این کلاس ایجاد کنم و بعد ازش توی یکی از کلاسهام استفاده کنم.
برنامه هم تحت کنسوله. یعنی فرمی ندارم که بخوام موقع ایجاد فرم ترد رو ایجاد کنم.
چی کار باید بکنم؟
از تابع Sleep استفاده کنید.نمونه رو بیینید: