আপনি কীভাবে একটি সি # কনসোল অ্যাপ্লিকেশনটিতে টাইমার যুক্ত করবেন


132

কেবল এটি - আপনি কীভাবে একটি সি # কনসোল অ্যাপ্লিকেশনটিতে টাইমার যুক্ত করবেন? আপনি যদি কিছু উদাহরণ কোডিং সরবরাহ করতে পারেন তবে দুর্দান্ত হবে।


16
সতর্কতা: উত্তরগুলির এখানে একটি বাগ রয়েছে, টাইমার অবজেক্টটি আবর্জনা সংগ্রহ করতে চলেছে। এটি টিক রাখার বিষয়টি নিশ্চিত করার জন্য টাইমারটির রেফারেন্সটি একটি স্ট্যাটিক ভেরিয়েবলে অবশ্যই সংরক্ষণ করতে হবে।
হ্যানস প্যাস্যান্ট

@ হ্যান্সপাসান্ট আপনি আমার উত্তরে পরিষ্কার বিবৃতিটি মিস করেছেন বলে মনে হয়: "সর্বদা একটি স্ট্যাটিক (ভিবি.এনইটি শেয়ার করা) সিস্টেম ব্যবহার করারও পরামর্শ দেওয়া হয়। থ্রেডিং.টাইমার আপনি যদি উইন্ডোজ পরিষেবা বিকাশ করে থাকেন এবং পর্যায়ক্রমে চালনার জন্য টাইমার প্রয়োজন হয় তবে এটি সম্ভবত আপনার টাইমার অবজেক্টের অকালীন আবর্জনা সংগ্রহ এড়াবে। " লোকেরা যদি এলোমেলো উদাহরণটি অনুলিপি করতে এবং অন্ধভাবে এটি ব্যবহার করতে চায় তবে এটাই তাদের সমস্যা।
অ্যাশ

উত্তর:


120

এটি খুব সুন্দর, তবে কিছুটা সময় অনুকরণের জন্য আমাদের একটি কমান্ড চালানো দরকার যা কিছুটা সময় নেয় এবং এটি দ্বিতীয় উদাহরণে খুব স্পষ্ট।

যাইহোক, কিছু কার্যকারিতা চিরকালের জন্য লুপের জন্য ব্যবহারের স্টাইলটিতে প্রচুর ডিভাইস সংস্থান লাগে এবং এর পরিবর্তে আমরা আবর্জনা সংগ্রাহককে এর মতো কিছু করতে ব্যবহার করতে পারি।

আমরা সিডিআর এর মাধ্যমে সি # তৃতীয় এডের একই বই থেকে কোডটিতে এই পরিবর্তনটি দেখতে পাচ্ছি।

using System;
using System.Threading;

public static class Program {

   public static void Main() {
      // Create a Timer object that knows to call our TimerCallback
      // method once every 2000 milliseconds.
      Timer t = new Timer(TimerCallback, null, 0, 2000);
      // Wait for the user to hit <Enter>
      Console.ReadLine();
   }

   private static void TimerCallback(Object o) {
      // Display the date/time when this method got called.
      Console.WriteLine("In TimerCallback: " + DateTime.Now);
      // Force a garbage collection to occur for this demo.
      GC.Collect();
   }
}

3
খালিদ, এটি অত্যন্ত সহায়ক ছিল। ধন্যবাদ। কনসোল.ড্রেডলাইন () এবং জিসি.ক্লোকলেটটি আমার প্রয়োজনীয় ছিল।
শেঠ স্পিয়ারম্যান

9
@ র‌্যাল্ফ উইলগাস, কেন জিসি.কলেক্ট (); দরকার?
পুচাকজ

2
@ পুচাক্জ আমি কল করার বিন্দু দেখতে পাচ্ছি না GC.Collect()। সংগ্রহ করার মতো কিছুই নেই। এটি অর্থবহ হয়ে উঠবে, যদি GC.KeepAlive(t)পরে বলা হয়Console.ReadLine();
নিউ প্রিন্ট

1
এটি প্রথম কলব্যাকের পরে শেষ হয়েছে
BadPiggie

1
@ খালিদ আল হাজামি "তবে, চিরকালের জন্য কিছু কার্যকারিতা করার জন্য লুপের ব্যবহারের ধরণটিতে অনেকগুলি ডিভাইস সংস্থান লাগে এবং পরিবর্তে আমরা আবর্জনা সংগ্রাহককে এরকম কিছু করার জন্য ব্যবহার করতে পারি।" এটি পরম অযৌক্তিক আবর্জনা। আবর্জনা সংগ্রহকারী একেবারেই অপ্রাসঙ্গিক। আপনি কি এটি কোনও বই থেকে অনুলিপি করেছেন এবং আপনি কী অনুলিপি করছেন তা বুঝতে পারছেন না?
অ্যাশ

65

System.Treadread.Timer ক্লাস ব্যবহার করুন।

System.Windows. Forms.Timer সাধারণত একক থ্রেডে সাধারণত উইন্ডোজ ফর্ম UI থ্রেড ব্যবহারের জন্য ডিজাইন করা হয়।

.NET কাঠামোর বিকাশে প্রথম দিকে একটি সিস্টেম.টাইমার ক্লাস যুক্ত করা হয়েছে। তবে এটি সাধারণত System.Threading.Timer ক্লাস ব্যবহার করার পরামর্শ দেওয়া হয় কারণ এটি সিস্টেমের চারপাশে কেবল একটি মোড়ক। থ্রেডিং। টাইমার যাইহোক।

আপনি যদি একটি উইন্ডোজ পরিষেবা বিকাশ করে থাকেন এবং পর্যায়ক্রমে চালনার জন্য টাইমার প্রয়োজন হয় তবে সর্বদা একটি স্থিতিশীল (ভিবি.এনইটি তে ভাগ করা হয়েছে) সিস্টেম ব্যবহার করার পরামর্শ দেওয়া হয়। এটি সম্ভবত আপনার টাইমার অবজেক্টের অকাল বর্জ্য সংগ্রহ এড়াবে।

কনসোল অ্যাপ্লিকেশনটিতে টাইমারটির উদাহরণ এখানে:

using System; 
using System.Threading; 
public static class Program 
{ 
    public static void Main() 
    { 
       Console.WriteLine("Main thread: starting a timer"); 
       Timer t = new Timer(ComputeBoundOp, 5, 0, 2000); 
       Console.WriteLine("Main thread: Doing other work here...");
       Thread.Sleep(10000); // Simulating other work (10 seconds)
       t.Dispose(); // Cancel the timer now
    }
    // This method's signature must match the TimerCallback delegate
    private static void ComputeBoundOp(Object state) 
    { 
       // This method is executed by a thread pool thread 
       Console.WriteLine("In ComputeBoundOp: state={0}", state); 
       Thread.Sleep(1000); // Simulates other work (1 second)
       // When this method returns, the thread goes back 
       // to the pool and waits for another task 
    }
}

জেফ রিখর র সিএলআর ভায়া সি # বইটি থেকে । এই বইটি 23 তম অনুচ্ছেদে 3 ধরণের টাইমারগুলির পিছনে যৌক্তিকতা বর্ণনা করে highly


আপনি প্রকৃত কোডিং সম্পর্কে আরও কিছু তথ্য সরবরাহ করতে পারেন?
জোহান ব্রেসলার

এমএসডিএন এর উদাহরণটি কি আপনার জন্য কাজ করে? এমএসডিএন.মাইক্রোসফট.ইন- ইউএস
এরিক টটলম্যান

এরিক, আমি এটি চেষ্টা করে দেখিনি তবে এতে সমস্যা থাকলে অস্বাভাবিক হবে না। আমি লক্ষ্য করেছি যে এটি কিছু ধরণের আন্ত-থ্রেড সিঙ্ক্রোনাইজেশন করার চেষ্টা করছে, এটি ঠিক এমন একটি অঞ্চল যা সঠিকভাবে পেতে জটিল can আপনি যদি এটি আপনার ডিজাইনে এড়াতে পারেন তবে এটি করা সর্বদা স্মার্ট।
অ্যাশ

1
অ্যাশ - আমি অবশ্যই এমএসডিএন উদাহরণগুলির সাথে একমত। আমি তত্ক্ষণাত সিঙ্ক্রোনাইজেশন কোডটি ছাড় দেব না, যদি টিমারটি নিজস্ব থ্রেডে চালিত হয়, তবে আপনি একটি বহু-থ্রেডযুক্ত অ্যাপ্লিকেশন লিখছেন এবং সিঙ্ক্রোনাইজেশন সম্পর্কিত বিষয়ে সচেতন হওয়া প্রয়োজন।
এরিক টটলম্যান

1
যদি এমন একাধিক পদ্ধতি থাকে যা টাইমারক্যালব্যাক প্রতিনিধি স্বাক্ষরের সাথে মেলে?
ওজকান

22

একটি সাধারণ একটি দ্বিতীয় টাইমার টিক তৈরি করতে কোডটি এখানে:

  using System;
  using System.Threading;

  class TimerExample
  {
      static public void Tick(Object stateInfo)
      {
          Console.WriteLine("Tick: {0}", DateTime.Now.ToString("h:mm:ss"));
      }

      static void Main()
      {
          TimerCallback callback = new TimerCallback(Tick);

          Console.WriteLine("Creating timer: {0}\n", 
                             DateTime.Now.ToString("h:mm:ss"));

          // create a one second timer tick
          Timer stateTimer = new Timer(callback, null, 0, 1000);

          // loop here forever
          for (; ; )
          {
              // add a sleep for 100 mSec to reduce CPU usage
              Thread.Sleep(100);
          }
      }
  }

এবং এখানে ফলাফল ফলাফল:

    c:\temp>timer.exe
    Creating timer: 5:22:40

    Tick: 5:22:40
    Tick: 5:22:41
    Tick: 5:22:42
    Tick: 5:22:43
    Tick: 5:22:44
    Tick: 5:22:45
    Tick: 5:22:46
    Tick: 5:22:47

সম্পাদনা করুন: হার্ড স্পিন লুপগুলি কোডে যুক্ত করা কখনই ভাল ধারণা নয় কারণ তারা কোনও লাভের জন্য সিপিইউ চক্র গ্রহণ করে। এই ক্ষেত্রে থ্রেডের ক্রিয়াগুলি পর্যবেক্ষণ করার অনুমতি দিয়ে অ্যাপ্লিকেশনটি বন্ধ হওয়া থেকে থামানোর জন্য লুপটি যুক্ত করা হয়েছিল। তবে সঠিকতার স্বার্থে এবং সিপিইউ ব্যবহার হ্রাস করার জন্য সেই লুপটিতে একটি সাধারণ স্লিপ কল যুক্ত করা হয়েছিল।


7
(;;) For for এর জন্য 100% সিপিইউ ব্যবহারের কারণ হয়।
শেঠ স্পিয়ারম্যান

1
লুপের জন্য যদি আপনার অসীম থাকে তবে এটি মোটামুটি সুস্পষ্ট নয় তবে এর ফলে সিপিইউ 100% হয়ে যাবে। এটি ঠিক করার জন্য আপনাকে লুপটিতে একটি স্লিপ কল যুক্ত করতে হবে।
16:55

3
লুপের জন্য কিছুক্ষণ লুপ হওয়া উচিত এবং কেন সিপিইউ 100% এ যায় তার উপর কত লোক স্থির হয় তা অবাক করা যায়। গাছের জন্য কাঠ মিস করার কথা! আজিমুথ, আমি ব্যক্তিগতভাবে জানতে চাই যে কীভাবে (1) লুপের জন্য অসীমের চেয়ে আলাদা হবে? অবশ্যই যে লোকেরা সিএলআর সংকলক অপ্টিমাইজার লিখেছেন তারা নিশ্চিত করবে যে এই দুটি কোড কনস্ট্রাক্টস ঠিক একই সিএলআর কোড তৈরি করেছে?
ব্লেক 7

1
(১) কাজ না করার কারণের কারণটি এটি বৈধ নয় c #: test.cs (21,20): ত্রুটি CS0031: ধ্রুবক মান '1' একটি '
বুল'তে

1
আমার মেশিনে নেই (win8.1, i5), প্রায় 20-30%, আপনি কী ধরণের কম্পিউটারে ফিরে এসেছিলেন? @ শেঠস্পিয়ার
শিনজৌ

17

একটু মজা করি

using System;
using System.Timers;

namespace TimerExample
{
    class Program
    {
        static Timer timer = new Timer(1000);
        static int i = 10;

        static void Main(string[] args)
        {            
            timer.Elapsed+=timer_Elapsed;
            timer.Start(); Console.Read();
        }

        private static void timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            i--;

            Console.Clear();
            Console.WriteLine("=================================================");
            Console.WriteLine("                  DEFUSE THE BOMB");
            Console.WriteLine(""); 
            Console.WriteLine("                Time Remaining:  " + i.ToString());
            Console.WriteLine("");        
            Console.WriteLine("=================================================");

            if (i == 0) 
            {
                Console.Clear();
                Console.WriteLine("");
                Console.WriteLine("==============================================");
                Console.WriteLine("         B O O O O O M M M M M ! ! ! !");
                Console.WriteLine("");
                Console.WriteLine("               G A M E  O V E R");
                Console.WriteLine("==============================================");

                timer.Close();
                timer.Dispose();
            }

            GC.Collect();
        }
    }
}

11

বা Rx ব্যবহার করে, সংক্ষিপ্ত এবং মিষ্টি:

static void Main()
{
Observable.Interval(TimeSpan.FromSeconds(10)).Subscribe(t => Console.WriteLine("I am called... {0}", t));

for (; ; ) { }
}

1
সেরা সমাধান, সত্যিই!
দিমিত্রি লেডেন্টসভ

8
খুব অপঠনযোগ্য এবং সেরা অনুশীলনের বিরুদ্ধে। এটি দুর্দান্ত দেখতে লাগে তবে উত্পাদনে ব্যবহার করা উচিত নয় কারণ কিছু পিপিএল ডাব্লুটিএফএফ যায় এবং নিজেরাই জুড়ে দেয়।
পাইটর কুলা

2
প্রতিক্রিয়াশীল এক্সটেনশনগুলি (আরএক্স) 2 বছর ধরে সক্রিয়ভাবে বিকাশিত হয়নি। এছাড়াও উদাহরণগুলি প্রসঙ্গ এবং বিভ্রান্তিকর ছাড়াই। চিত্রগুলি বা প্রবাহের উদাহরণগুলি জানা খুব কম Little
জেমস বেইলি

4

আপনি যদি আরও কিছু নিয়ন্ত্রণ চান তবে আপনি সম্ভবত সঠিকতা এবং আরও বেশি কোড / জটিলতা চান তবে আপনি নিজের টাইমিং পদ্ধতিগুলিও ব্যবহার করতে পারেন তবে আমি এখনও একটি টাইমার প্রস্তাব করব। আপনার যদি সত্যিকারের টাইমিং থ্রেডের নিয়ন্ত্রণ থাকতে হয় তবে এটি ব্যবহার করুন:

private void ThreadLoop(object callback)
{
    while(true)
    {
        ((Delegate) callback).DynamicInvoke(null);
        Thread.Sleep(5000);
    }
}

আপনার টাইমিং থ্রেড হবে (যখন রিকিউর হয়ে যায় তখন থামাতে এটি পরিবর্তন করুন, এবং যে কোনও সময় বিরতিতে আপনি চান)।

এবং ব্যবহার করতে / শুরু করতে আপনি করতে পারেন:

Thread t = new Thread(new ParameterizedThreadStart(ThreadLoop));

t.Start((Action)CallBack);

কলব্যাক হ'ল আপনার অকার্যকর প্যারামিটারলেস পদ্ধতি যা আপনি প্রতিটি বিরতিতে কল করতে চান। উদাহরণ স্বরূপ:

private void CallBack()
{
    //Do Something.
}

1
যদি আমি সময় শেষ না হওয়া পর্যন্ত ব্যাচের কাজ চালাতে চাই তবে আপনার পরামর্শটি কি এখানে সেরা হবে?
জোহান ব্রেসেলার

1

আপনি নিজের তৈরিও করতে পারেন (উপলভ্য বিকল্পগুলি থেকে অসন্তুষ্ট হলে)।

আপনার নিজস্ব Timerবাস্তবায়ন তৈরি করা বেশ বেসিক স্টাফ।

এটি এমন একটি অ্যাপ্লিকেশনের জন্য একটি উদাহরণ যা আমার কোডবেসের বাকী অংশের মতো একই থ্রেডে COM অবজেক্ট অ্যাক্সেসের প্রয়োজন।

/// <summary>
/// Internal timer for window.setTimeout() and window.setInterval().
/// This is to ensure that async calls always run on the same thread.
/// </summary>
public class Timer : IDisposable {

    public void Tick()
    {
        if (Enabled && Environment.TickCount >= nextTick)
        {
            Callback.Invoke(this, null);
            nextTick = Environment.TickCount + Interval;
        }
    }

    private int nextTick = 0;

    public void Start()
    {
        this.Enabled = true;
        Interval = interval;
    }

    public void Stop()
    {
        this.Enabled = false;
    }

    public event EventHandler Callback;

    public bool Enabled = false;

    private int interval = 1000;

    public int Interval
    {
        get { return interval; }
        set { interval = value; nextTick = Environment.TickCount + interval; }
    }

    public void Dispose()
    {
        this.Callback = null;
        this.Stop();
    }

}

আপনি ইভেন্টগুলি নিম্নলিখিত হিসাবে যুক্ত করতে পারেন:

Timer timer = new Timer();
timer.Callback += delegate
{
    if (once) { timer.Enabled = false; }
    Callback.execute(callbackId, args);
};
timer.Enabled = true;
timer.Interval = ms;
timer.Start();
Window.timers.Add(Environment.TickCount, timer);

টাইমার কাজ করে তা নিশ্চিত করার জন্য আপনাকে নিম্নলিখিত হিসাবে অন্তহীন লুপ তৈরি করতে হবে:

while (true) {
     // Create a new list in case a new timer
     // is added/removed during a callback.
     foreach (Timer timer in new List<Timer>(timers.Values))
     {
         timer.Tick();
     }
}

1

সি # 5.0+ এবং। নেট ফ্রেমওয়ার্ক 4.5+ এ আপনি async ব্যবহার করতে / অপেক্ষা করতে পারেন:

async void RunMethodEvery(Action method, double seconds)
{
    while (true)
    {
        await Task.Delay(TimeSpan.FromSeconds(seconds));
        method();
    }
 }

0

ডক

সেখানে আপনি এটি :)

public static void Main()
   {
      SetTimer();

      Console.WriteLine("\nPress the Enter key to exit the application...\n");
      Console.WriteLine("The application started at {0:HH:mm:ss.fff}", DateTime.Now);
      Console.ReadLine();
      aTimer.Stop();
      aTimer.Dispose();

      Console.WriteLine("Terminating the application...");
   }

   private static void SetTimer()
   {
        // Create a timer with a two second interval.
        aTimer = new System.Timers.Timer(2000);
        // Hook up the Elapsed event for the timer. 
        aTimer.Elapsed += OnTimedEvent;
        aTimer.AutoReset = true;
        aTimer.Enabled = true;
    }

    private static void OnTimedEvent(Object source, ElapsedEventArgs e)
    {
        Console.WriteLine("The Elapsed event was raised at {0:HH:mm:ss.fff}",
                          e.SignalTime);
    }

0

আমি আপনাকে মাইক্রোসফ্টের নির্দেশিকা অনুসরণ করার পরামর্শ দিই ( https://docs.microsoft.com/en-us/dotnet/api/system.timers.timer.interval?view=netcore-3.1 )।

আমি প্রথমে ব্যবহার System.Threading;করার চেষ্টা করেছি

var myTimer = new Timer((e) =>
{
   // Code
}, null, TimeSpan.Zero, TimeSpan.FromSeconds(5));

কিন্তু এটি অবিরত continuously 20 মিনিটের পরে বন্ধ হয়ে যায়।

এটির সাথে, আমি সমাধানগুলির সেটিংটি চেষ্টা করেছি

GC.KeepAlive(myTimer)

অথবা

for (; ; ) { }
}

তবে তারা আমার ক্ষেত্রে কাজ করেনি।

মাইক্রোসফ্ট ডকুমেন্টেশন অনুসরণ করে, এটি নিখুঁতভাবে কাজ করেছে:

using System;
using System.Timers;

public class Example
{
    private static Timer aTimer;

    public static void Main()
    {
        // Create a timer and set a two second interval.
        aTimer = new System.Timers.Timer();
        aTimer.Interval = 2000;

        // Hook up the Elapsed event for the timer. 
        aTimer.Elapsed += OnTimedEvent;

        // Have the timer fire repeated events (true is the default)
        aTimer.AutoReset = true;

        // Start the timer
        aTimer.Enabled = true;

        Console.WriteLine("Press the Enter key to exit the program at any time... ");
        Console.ReadLine();
    }

    private static void OnTimedEvent(Object source, System.Timers.ElapsedEventArgs e)
    {
        Console.WriteLine("The Elapsed event was raised at {0}", e.SignalTime);
    }
}
// The example displays output like the following: 
//       Press the Enter key to exit the program at any time... 
//       The Elapsed event was raised at 5/20/2015 8:48:58 PM 
//       The Elapsed event was raised at 5/20/2015 8:49:00 PM 
//       The Elapsed event was raised at 5/20/2015 8:49:02 PM 
//       The Elapsed event was raised at 5/20/2015 8:49:04 PM 
//       The Elapsed event was raised at 5/20/2015 8:49:06 PM 
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.