A
A
Alexander Dubina2013-09-06 14:44:25
Mobile development
Alexander Dubina, 2013-09-06 14:44:25

Asynchronous start of many timers?

It is necessary to make the characters fall. Like in the movie The Matrix.
I did this in JS. There were no particular problems. Now you need to do the same under WP in C#.
I started doing it and ran into a problem: when the timer is started and the necessary function is attached to it in the loop, the loop does not go through, because it waits for the timer to run out.
Here's what I did:
Create a grid of items. which will then change. Everything is working.

public partial class MainPage : PhoneApplicationPage
    {
//координаты для изменения координат клеточки, в которой меняется символ
        int x;
        int y;
        // Конструктор
        public MainPage()
        {
            InitializeComponent();
            double ScreenWidth = System.Windows.Application.Current.Host.Content.ActualWidth;
            double ScreenHeight = System.Windows.Application.Current.Host.Content.ActualHeight;

            int i, j, countWidth, countHeight, count = 0;
            bool flag = false;
//Количество ячеек
            countWidth = (int)Math.Round(ScreenWidth / 50);
            countHeight = (int)Math.Round(ScreenHeight / 50);

            Random random = new Random();

            if (flag == false)
            {
                for (i = 0; i < countWidth; i++)
                {
                    for (j = 0; j < countHeight; j++)
                    {
                        TextBlock asd = new TextBlock();
                        asd.Name = "TB_" + i + "_" + j;  //имя, по которому буду находить элемент для изменения его содержимого
                        asd.Text = char.ConvertFromUtf32(random.Next(0x4E00, 0x4FFF));
                        int wx = i * 50;
                        int wy = j * 50;
                        asd.Foreground = new SolidColorBrush(Colors.Green);
                        asd.Margin = new Thickness(wx, wy, 0, 0);
                        asd.FontSize = 36;
                        LayoutRoot.Children.Add(asd);
                    }
                }
                flag = true;
            }

            // Пример кода для локализации ApplicationBar
            //BuildLocalizedApplicationBar();
        }

Clicking on the screen launches the Matrix. More precisely, it should start. So far, only 1 character is working, which does not even want to move.
private void TapMainGrid(object sender, System.Windows.Input.GestureEventArgs e)
        {
            double ScreenWidth = System.Windows.Application.Current.Host.Content.ActualWidth;
            double ScreenHeight = System.Windows.Application.Current.Host.Content.ActualHeight;

            int i, j, countWidth, countHeight, count = 0;

            countWidth = (int)Math.Round(ScreenWidth / 50);
            countHeight = (int)Math.Round(ScreenHeight / 50);

            Random random = new Random();

            

            this.x = 0;
            for (i = 0; i < countWidth; i++)
            {
//Так же не понял, как передать аргумент в событие, поэтому меняю глобальную переменную.
//Теоретически должен падать 1 меняющийся символ.
                this.y = i;

                var stopHandle = EasyTimer.SetInterval(() =>
                {
                    TimerCallback1();                                                             /!!!!!!!!!!!!!!!!Тут проблема. Цикл не отрабатывает, пока работает счетчик. А мне нужно, тоб паралельно куча таких работала.
                    // --- You code here ---
                    // This piece of code will run after every 1000 ms
                    // To stop the timer, just dispose off the stop handle

                }, 100);

               
                
            }/*
            DispatcherTimer newTimer = new DispatcherTimer();
            newTimer.Interval = TimeSpan.FromSeconds(0.1);
            newTimer.Tick += TimerCallback;
            newTimer.Start();*/
        }

The function of changing the cell and the symbol in it
public void  TimerCallback1()
        {

            Random random = new Random();
            string asdf = "TB_" + this.x + "_" + this.y;
            object wantedNode = LayoutRoot.FindName(asdf);
            TextBlock txt = (TextBlock)wantedNode;
            txt.Text = char.ConvertFromUtf32(random.Next(0x4E00, 0x4FFF));
        }

Timer class. Found on the Internet. I had to redo it to work on WP.
public static class EasyTimer
    {
        public static IDisposable SetInterval(Action method, int delayInMilliseconds)
        {
            DispatcherTimer timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromSeconds(delayInMilliseconds/1000);
            timer.Tick += (source, e) =>
            {
                method();
            };

            //timer.Enabled = true;
            timer.Start();

            // Returns a stop handle which can be used for stopping
            // the timer, if required
            return timer as IDisposable;
        }
        /*
        public static IDisposable SetTimeout(Action method, int delayInMilliseconds)
        {
            System.Timers.Timer timer = new System.Timers.Timer(delayInMilliseconds);
            timer.Elapsed += (source, e) =>
            {
                method();
            };

            timer.AutoReset = false;
            timer.Enabled = true;
            timer.Start();

            // Returns a stop handle which can be used for stopping
            // the timer, if required
            return timer as IDisposable;
        }*/
    }

Tried adding async to the SetInterval method of the EasyTimer class. Writes that it cannot be used with IDisposable.
The problem is that I started to dig more deeply, but I don’t understand asynchronous function calls and events (hung on a timer) yet.
Perhaps tell me how to do this for this implementation, or maybe there are errors in my logic.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Alexander Dubina, 2013-09-29
@struggleendlessly

One of the solutions I found can be found here .

G
gleb_kudr, 2013-09-06
@gleb_kudr

It's worth starting with the fact that there are at least two timer classes for working in .net - System.Timers.Timer
and System.Threading.Timer. You need to specify which one you are using.
By design, I would have one timer for all objects. I would make it spin in the background thread. Every N milliseconds, it would call the procedure for processing the array of points.
On each tick, go through all the elements and check if the processing time has come up. If the processing time has come up, update the element in the UI thread and assign the next processing time.
I don’t like assigning a timer to each element - you can get bored later with threads and their interaction.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question