Home > Software design >  WinForms: A slogan change function with threading
WinForms: A slogan change function with threading

Time:05-04

It is 7 slogans at the bottom of a form, that changes randomly every 3 min.

It must only be done with threading.

Here is my code:

      MessagePrinter printer1 = new MessagePrinter();

      Thread thread1 = new Thread ( new ThreadStart( printer1.Print ) );

      thread1.Name = "Slogan 1";

      MessagePrinter printer2 = new MessagePrinter();
      Thread thread2 = new Thread ( new ThreadStart( printer2.Print ) );
      thread2.Name = "Slogan 2";

      MessagePrinter printer3 = new MessagePrinter();
      Thread thread3 = new Thread ( new ThreadStart( printer3.Print ) );
      thread3.Name = "Slogan 3";
      
       thread1.Start();
      thread2.Start();
      thread3.Start();

      Console.WriteLine( "Slogans" );
        Console.ReadLine();

But how do i make it random? And this is in console, i have no idea how to make this in WinForms.

Also i am new to coding back-end, so i'm sorry if i'm just misunderstanding something very basic

CodePudding user response:

It must only be done with threading

This is not very clear. All running code is running on a thread, so in some sense all code is 'threaded'. And UI frameworks like winforms are explicitly single threaded, so it is not like you can only use background threads. And you example does not really help much since there is no hint of doing anything periodically, nor randomly.

To do anything periodically you should use a timer. If you pick a timer that is executes its event on a background thread you need to post the actual UI update to the UI thread, one way to do this is with Control.Invoke. You could in theory use a loop that does something and then sleep for the period interval, but this is poor practice that I would not recommend adopting.

To get some pseudo random number you would typically use the Random class. If you want to lookup a random value in a list you would typically write something like:

var myRandomItem = myList[myRandom.Next( myList.Count)];

putting it together could look something like

private void OnTimerTick(object sender, ElapsedEventArgs e){
    var randomSlogan= mySlogans[myRandom.Next( mySlogans.Count)];
    myForm.Invoke(() => myForm.MyTextBox.Text = randomSlogan);
}

But there is very little point in using a background thread just to lookup a random item. They should normally be reserved for operations that actually take a measurable amount of time.

CodePudding user response:

As already said, you would normally do this with a Timer or BackgroundWorker. If you have to explicitly startup your own thread, you could try something like this:

private readonly Random _rnd = new Random();
private readonly List<string> _slogans = new List<string> { "a", "b", "c" };
private readonly Thread _thread;
private void UpdateSlogan()
{
    while (true)
    {
        var slogan = _slogans[_rnd.Next(_slogans.Count)];
        textBox1.BeginInvoke(new Action(() => textBox1.Text = slogan));

        Thread.Sleep(TimeSpan.FromMinutes(3));
    }
}

public Form1()
{
    InitializeComponent();
    _thread = new Thread(UpdateSlogan);
}

Somewhere else in the code you then have to call

_thread.Start();

and the thing is going to run. Be aware, that this code doesn't contain anything to close this thread. You have to implement some kind of stopping mechanism (like checking a CancellationToken or similar) and picking a random element means also, the same element could be picked multiple times. Maybe you have to ensure, that random picks something else as the current used slogan, but that's another question.

  • Related