اجرای کد در بازه های زمانی مشخص در C#

مطلب که امروز در نظر گرفتم، در حقیقت راه حل مشکل خود من تو دوتا مساله بود. اول اجرا شدن یه کد، در بازه های زمانی مشخص، یعنی مثلا خوندن چندتا رکورد تازه بروز شده از دیتابیس و نشون دادنش به کاربر، دومی راه حل ping کردن یه سرور یا یه مقصد تو شبکه. Ping کردن که با ارسال بسته های ICMP انجام میگیره، در حقیقت به شما میگه که سرور یا مقصد مورد نظرتون تو  شبکه ی مشخص، که قطعا IP Address داره، اماده پاسخ گویی به شما هست یا نه. به نظرم شما حتما این کار رو قبلا از طریق Command line سیستم عامل انجام داده باشید. یه همچین شکلی داره معمولا:

بابک فخریلو

فرض کنید برنامه ای را نیاز دارید که بخواهد به طور مداوم شبکه را مورد بررسی قرار دهد، یا برنامه ای که بخواهد مثلا هر هشت ساعت  به طور خودکار یک گزارش برای تحلیل گران تجاری تولید کند. با استفاده از زبان C#، پیاده سازی چنین نیاز نرم افزاری وجود دارد. در این مطلب به استفاده از کلاس  System.Timers.Timer می پردازیم که راه حل مشکل ماست.

یک سناریوی ساده

فرض کنید سروری داریم که به درخواست های  ICMP که از کامپیوترهای درون شبکه فرستاده می شود پاسخ می دهد (بیرون یا درونش اینجا فرقی نمی کنه، وارد مباحث تخصصی شبکه نکنید منو!). حالا می خواهیم برنامه ای بنویسیم که توانایی سرور را در پاسخ به درخواست های ICMP، بسنجیم.

یک برنامه با C# خواهیم نوشت که بسته های ICMP را هر پنج دقیقه یک بار به سرور ارسال می کند. سپس پاسخ های دریافتی را هم در یک فایل txt ساده ذخیره یا به عبارتی log خواهید کرد.

کلاس PingLogger

خوب، منطق برنامه (business logic) را در کلاسی به نام PingLogger قرار می دهیم:

using System;
using System.IO;
using System.Net.NetworkInformation;
using System.Timers;
using System.Text;

public class PingLogger
{
private string _remoteHostAddress;
private Timer _pingTimer;
private Ping _ping;
private StreamWriter _logFileWriter;

public PingLogger(string remoteHostAddress)
{
this._remoteHostAddress = remoteHostAddress;

// Configure a Timer for use
this._pingTimer = new Timer();
this._pingTimer.Interval = 300000;
this._pingTimer.Elapsed += new ElapsedEventHandler(this.TimeElapsed);
this._pingTimer.Enabled = true;

this._ping = new Ping();

// Gain write access to serverPingStatus.txt
FileStream fileStream = File.Open("serverPingStatus.txt",
FileMode.Append, FileAccess.Write);
this._logFileWriter = new StreamWriter(fileStream);

} // end public PingLogger()

private void PingRemoteHost()
{
// Print the time that we try to ping the remote address
this._logFileWriter.Write("[");
this._logFileWriter.Write(System.DateTime.Now.ToString());
this._logFileWriter.Write("] ");
try
{
PingReply reply = this._ping.Send(this._remoteHostAddress, 3000);

if (reply.Status == IPStatus.Success)
{
this._logFileWriter.Write("Successful ICMP response from ");
this._logFileWriter.Write(this._remoteHostAddress);
this._logFileWriter.Write(". Round Trip Time: ");
this._logFileWriter.Write(reply.RoundtripTime);
this._logFileWriter.Write(" milliseconds.");
}
else
{
this._logFileWriter.Write("Unsuccessful ICMP response from ");
this._logFileWriter.Write(this._remoteHostAddress);
this._logFileWriter.Write("Status of ICMP response: ");
this._logFileWriter.Write(reply.Status);

} // end if
}
catch (Exception ex) {
this._logFileWriter.Write("Encountered problem while pinging ");
this._logFileWriter.Write(this._remoteHostAddress);
this._logFileWriter.Write(". Error message: ");
this._logFileWriter.Write(ex.Message);
} // end try-catch

this._logFileWriter.WriteLine();
this._logFileWriter.Flush();

} // end private void PingRemoteHost()

private void TimeElapsed(Object sender, ElapsedEventArgs eventArgs)
{
PingRemoteHost();
} // end private void TimeElapsed()

} // end public class PingLogger

تنظیم System.Timers.Timer برای انجام binding مورد نظر شما

در constructor کلاس، ابتدا یک نمونه از System.Timers.Timer را مقدار دهی اولیه می کنیم و بعد تنظیمات لازم را روی آن انجام می دهیم:

بازه زمانی مورد نظر برای اجرای دوره ای کد. مقدار 300000 را به خاصیت Interval شی pingTimer  می دهیم تا مشخص کنیم می خواهیم کد هر 300000 میلی ثانیه یک بار، یا به عبارتی 5 دقیقه یک بار اجرا شود.

کدی که می خواهیم اجرا شود. متد TimeElapsed  را با  یک delegate به نام System.Timers.ElapsedEventHandler مقدار دهی کردیم و آن را به رویداد Elapsed   اضافه کردیم، به عبارتی یک handler تعریف کردیم.

یک نشان برای راه اندازی pingTimer  جهت آغاز شمارش زمان.  خاصیت Enabled  از شی pingTimer  را به true مقدار دهی می کنیم تا شمارشگر شروع به کار کند. اولین اجرای رویداد Elapsed   بعد از 5 دقیقه از زمانی شروع خواهد شد که Enabled  را مقدار دهی کردید.

بعد از این که شی pingTimer  حالا هر پنج دقیقه یک بار، متد PingRemoteHost   اجرا خواهد شد.

چگونگی ارسال بسته ی ICMP

در هنگام مقدار دهی اولیه ی از کلاس PingLogger ، ابتدا یک نمونه از کلاس System.Net.NetworkInformation.Ping  را با شی به نام _ping ایجاد کردیم.

حالا وقتی که PingRemoteHost   فراخوانی می شود، متد Send    از شی ping  را صدا می زنیم تا یک درخواست ICMP را به مقصد مورد نظر خودمان ارسال کنیم. این فراخوانی یک نمونه از کلاس System.Net.NetworkInformation.PingReply را در پاسخ برای ما بر می گرداند که حاوی اطلاعات خروجی درخواست ICMP است.

چطور پاسخ ها را log کنیم

برای نوشتن پاسخ های دریافتی در یک فایل، یک نمونه از System.IO.StreamWriter   ایجاد می کنیم . این کار اجازه دسترسی نوشتن به فایل serverPingStatus.txt.  را می دهد.

وقتی متد PingRemoteHost  اجرا می شود، ابتدا تاریخ جاری را در فایل می  نویسیم. داده هایی بعدی که می نویسیم، موارد زیر را شامل می شود:

نوشتن جزئیات خطا، در صورت بروز. در صورتی که درخواست ما با خطا روبرو شود، آدرس سرور مورد نظر را به همراه جزئیات پیام خطا (exception) در فایل می نویسیم.

موفقیت امیز بودن ping. اگر درخواست ما موفقیت آمیز بود و یک پاسخ از سرور گرفتیم، پیام موفقیت آمیز بودن را می نویسیم، و در پی آن زمان رفت و برگشت بسته ی درخواستی را هم به میلی ثانیه، در فایل ذخیره می کنیم.

موفق نبودن ping. وقتی پاسخی از درخواست خود نداشته باشیم، وضعیت پیام ICMP دریافتی را ذخیره می کنیم.

استفاده از کلاس ساخته شده

حالا که منطق کاری برنامه در کلاس PingLogger  کپسوله شده، ایجاد یک برنامه ی Console که بتواند در بررسی وضعیت سرور ما را کمک کند، ساده خواهد بود:

public class Program
{
    public static void Main(string[] args)
    {
        PingLogger pingLogger = new PingLogger("192.168.0.1");
        Console.Read();
    } // end public static void Main(string[] args)
} // end class Program

همه آنچه که لازم است انجام دهیم ایجاد یک نمونه از کلاس PingLogger   است و فراخوانی Console.Read برای جلوگیری از بسته شدن برنامه در محیط Command است.

وقتی برنامه اجرا شد، تا زمانی که کلید Enter را برای  خروج از آن فشار ندهید، برنامه هر 5 دقیقه یک بار درخواست ping را به آدرس مورد نظر شما می فرستد و هر بار فایل serverPingStatus.txt را بروز می کند.

برگرفته از :

How to execute codes periodically in C#

دربارهٔ Persian Developer

I Love Developing applications

Posted on نوامبر 9, 2012, in NET., توسعه نرم افزار and tagged , , . Bookmark the permalink. ۱ دیدگاه.

  1. شما بلاخره رفتی سراغ برنامه نویسی سوکت…دمت گرم

پاسخی بگذارید

در پایین مشخصات خود را پر کنید یا برای ورود روی شمایل‌ها کلیک نمایید:

نشان‌وارهٔ وردپرس.کام

شما در حال بیان دیدگاه با حساب کاربری WordPress.com خود هستید. بیرون رفتن / تغییر دادن )

تصویر توییتر

شما در حال بیان دیدگاه با حساب کاربری Twitter خود هستید. بیرون رفتن / تغییر دادن )

عکس فیسبوک

شما در حال بیان دیدگاه با حساب کاربری Facebook خود هستید. بیرون رفتن / تغییر دادن )

عکس گوگل+

شما در حال بیان دیدگاه با حساب کاربری Google+ خود هستید. بیرون رفتن / تغییر دادن )

درحال اتصال به %s

%d وب‌نوشت‌نویس این را دوست دارند: