كيف يمكنني رفع الحدث كل ساعة (أو محددة الفاصل الزمني كل ساعة) في .الشبكة ؟

StackOverflow https://stackoverflow.com/questions/307798

  •  08-07-2019
  •  | 
  •  

سؤال

أنا أعمل على القليل الزاحف على شبكة الإنترنت التي سيتم تشغيلها في علبة النظام والزحف موقع على شبكة الإنترنت على مدار الساعة.

ما هي أفضل طريقة للحصول على .صافي لرفع الحدث كل ساعة أو بعض الأخرى الفاصل الزمني لأداء بعض المهام.على سبيل المثال أريد أن تشغيل الحدث كل 20 دقيقة على أساس الوقت.سيكون هذا الحدث أثار في:

00:20
00:40
01:00
01:20
01:40

وهلم جرا.أفضل طريقة يمكن القيام بذلك عن طريق إنشاء حلقة على موضوع, الذي يتحقق باستمرار إذا كان الوقت هو يقبل القسمة على فترة معينة و يثير رد الحدث إذا كان الوصول إلى وقت.أشعر أن هناك يجب أن يكون طريقة أفضل.

أود أن استخدام Timer لكن أفضل شيء أن يتبع "الجدول الزمني" الذي يعمل على مدار الساعة أو شيء على طول هذه الخطوط.

دون وضع طلبي في ويندوز "برنامج جدولة المهام" هل هذا ممكن ؟

تحديث:
انا إضافة خوارزمية حساب الفاصل الزمني الموقت.هذه الطريقة تستغرق وقتا "minute"المعلمة ، وهو ما الوقت الموقت يجب أن تؤدي إلى علامة.على سبيل المثال ، إذا كان "minute"المعلمة هو 20 ، ثم الموقت سوف القراد على فترات في الجدول الزمني أعلاه.

int CalculateTimerInterval(int minute)
{
    if (minute <= 0)
        minute = 60;
    DateTime now = DateTime.Now;

    DateTime future = now.AddMinutes((minute - (now.Minute % minute))).AddSeconds(now.Second * -1).AddMilliseconds(now.Millisecond * -1);

    TimeSpan interval = future - now;

    return (int)interval.TotalMilliseconds;
}

هذا الرمز يستخدم على النحو التالي:

static System.Windows.Forms.Timer t;
const int CHECK_INTERVAL = 20;


static void Main()
{
    t = new System.Windows.Forms.Timer();
    t.Interval = CalculateTimerInterval(CHECK_INTERVAL);
    t.Tick += new EventHandler(t_Tick);
    t.Start();
}

static void t_Tick(object sender, EventArgs e)
{
    t.Interval = CalculateTimerInterval(CHECK_INTERVAL);
}
هل كانت مفيدة؟

المحلول

النظام.توقيت.توقيت.إذا كنت تريد أن تعمل في أوقات محددة من اليوم, سوف تحتاج إلى معرفة كم من الوقت حتى في المرة القادمة وتعيين أنه فاصل الخاص بك.

هذه هي الفكرة الأساسية.اعتمادا على كم دقيقة تحتاج إلى أن يمكنك أن تفعل أكثر من ذلك.

int minutes = DateTime.Now.Minute;
int adjust = 10 - (minutes % 10);
timer.Interval = adjust * 60 * 1000;  

نصائح أخرى

قد تجد المساعدة من Quartz.net http://quartznet.sourceforge.net/

هنا هو مثال على نظام خفيف الوزن باستخدام الخيط توقيت و asynch الاتصال.

أعرف أن هناك بعض الجوانب السلبية ، ولكن أود أن استخدام هذا بدلا من توقيت عندما ركل قبالة منذ فترة طويلة عملية (مثل schedualed الخلفية الخدمات).لأنه يعمل مضمنة في توقيت الموضوع, كنت لا داعي للقلق حول الحصول انطلقت مرة أخرى قبل الإتصال الأصلي قد انتهى.هذا يمكن أن تمتد قليلا جدا أن تجعل من استخدام مجموعة من datetimes كما الزناد مرات أو إضافة بعض مزيد من القدرة على ذلك.أنا متأكد من أن البعض من رفاق هناك معرفة بعض طرق أفضل.

    public Form1()
    {
        InitializeComponent();

        //some fake data, obviously you would have your own.
        DateTime someStart = DateTime.Now.AddMinutes(1);
        TimeSpan someInterval = TimeSpan.FromMinutes(2);

        //sample call
        StartTimer(someStart,someInterval,doSomething);
    }

    //just a fake function to call
    private bool doSomething()
    {
        DialogResult keepGoing = MessageBox.Show("Hey, I did something! Keep Going?","Something!",MessageBoxButtons.YesNo);
        return (keepGoing == DialogResult.Yes);
    }

    //The following is the actual guts.. and can be transplanted to an actual class.
    private delegate void voidFunc<P1,P2,P3>(P1 p1,P2 p2,P3 p3);
    public void StartTimer(DateTime startTime, TimeSpan interval, Func<bool> action)
    {
        voidFunc<DateTime,TimeSpan,Func<bool>> Timer = TimedThread;
        Timer.BeginInvoke(startTime,interval,action,null,null);
    }

    private void TimedThread(DateTime startTime, TimeSpan interval, Func<bool> action)
    {
        bool keepRunning = true;
        DateTime NextExecute = startTime;
        while(keepRunning)
        {
            if (DateTime.Now > NextExecute)
            {
                keepRunning = action.Invoke();
                NextExecute = NextExecute.Add(interval);
            }
            //could parameterize resolution.
            Thread.Sleep(1000);
        }            
    }

استراتيجية أخرى هذا تسجيل آخر مرة كانت عملية تشغيل وتحديد ما إذا كان الفاصل الزمني المطلوب انقضت منذ ذلك الوقت.في هذه الاستراتيجية ، سوف رمز الحدث الخاص بك إلى النار إذا انقضى الوقت يساوي أو أكبر من الفاصل الزمني المطلوب.في هذه الطريقة يمكنك التعامل مع الحالات التي تكون فيها فترات طويلة (مرة واحدة في اليوم الواحد ، على سبيل المثال) يمكن أن يكون غاب إذا كان جهاز الكمبيوتر إلى أسفل لسبب ما.

لذلك على سبيل المثال:

  • lastRunDateTime = 5/2/2009 في 8 مساء
  • أريد أن أدير العملية كل 24 ساعة
  • على توقيت الحدث, تحقق ما إذا كان 24 ساعة أو أكثر مرت منذ آخر مرة كانت عملية تشغيل.
  • إذا نعم, تشغيل عملية تحديث lastRunDateTime بإضافة الفاصل الزمني المطلوب لذلك (24 ساعة في هذه الحالة ، ولكن كل ما تحتاجه هو أن يكون)

ومن الواضح أن هذا التعافي بعد النظام قد انخفض, سوف تحتاج إلى تخزين lastRunDateTime في ملف أو قاعدة بيانات في مكان ما حتى يمكن للبرنامج التقاط حيث توقفت على الانتعاش.

النظام.يقوم نظام ويندوز.أشكال.الموقت (أو نظام.توقيت.توقيت)

ولكن منذ الآن أنت تقول أنك لا تريد استخدام أجهزة ضبط الوقت ، يمكنك تشغيل خفيفة الوزن عملية الانتظار في موضوع آخر (التحقق من وقت النوم بضع ثوان ، تحقق مرة ثانية) أو المكون الذي يرفع الحدث (باستخدام خفيفة الوزن عملية الانتظار) على بعض المواعيد أو فترات

هدفي هو أن استيراد حوالي 03:00 كل ليلة.

هنا هو بلدي النهج باستخدام النظام.توقيت.الموقت:

private Timer _timer;
private Int32 _hours = 0;
private Int32 _runAt = 3;

protected override void OnStart(string[] args)
{
    _hours = (24 - (DateTime.Now.Hour + 1)) + _runAt;
    _timer = new Timer();
    _timer.Interval = _hours * 60 * 60 * 1000;
    _timer.Elapsed += new ElapsedEventHandler(Tick);
    _timer.Start();
}

void Tick(object sender, ElapsedEventArgs e)
{
    if (_hours != 24)
    {
        _hours = 24;
        _timer.Interval = _hours * 60 * 60 * 1000;
    }

    RunImport();
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top