Форум программистов, компьютерный форум, киберфорум
Наши страницы

C# для начинающих

Войти
Регистрация
Восстановить пароль
 
NewNoob
6 / 10 / 0
Регистрация: 29.05.2015
Сообщений: 633
Завершенные тесты: 1
#1

Thread.Sleep() - для какого потока вызывается? - C#

30.01.2017, 03:00. Просмотров 274. Ответов 9
Метки нет (Все метки)

Почему по вызову Thread.Sleep зависает основной поток,а не второстепенный?


C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/*
 /*
 * Сделано в SharpDevelop.
 * Пользователь: User
 * Дата: 28.01.2017
 * Время: 18:00
 * 
 * Для изменения этого шаблона используйте Сервис | Настройка | Кодирование | Правка стандартных заголовков.
 */
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;
 
namespace Game_Test
{
    /// <summary>
    /// Description of GameInterface.
    /// </summary>
    public partial class GameInterface : UserControl
    {
        Booxes box;
        public bool flag = false;
        
        public GameInterface()
        {
            //
            // The InitializeComponent() call is required for Windows Forms designer support.
            //
            InitializeComponent();
            box = new Booxes(MainForm.MainPath);
            
            //
            // TODO: Add constructor code after the InitializeComponent() call.
            //
        }
        
        void GameInterfacePaint(object sender, PaintEventArgs e)
        {
            
            if(!flag)
            {
                flag = true;
                DrawBooxes(e);
            }
            
            else
            {
                while(true)
                {
                    DrawBooxes(e);
                    Thread.Sleep(10000);
                }
            }
            
        }
        
        void DrawBooxes(PaintEventArgs e)
        {
            int x = 0;
            int y = 0;
            
            for (int i = 0;i<500;i++)
            {
                for (int j = 0;j<500;j++)
                {
                    e.Graphics.DrawImage(box.Box_Image,new Point(x,y));
                    y+=21;
                }
                
                x+=21;
                y=0;
            }
            
        }
        
        
    }
}
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/*
 * Сделано в SharpDevelop.
 * Пользователь: User
 * Дата: 28.01.2017
 * Время: 18:00
 * 
 * Для изменения этого шаблона используйте Сервис | Настройка | Кодирование | Правка стандартных заголовков.
 */
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;
 
namespace Game_Test
{
    /// <summary>
    /// Description of MainForm.
    /// </summary>
    /// 
    
    class Inform
    {
        
    }
    
    public partial class MainForm : Form
    {
        public const string MainPath = @"C:\Users\User\Documents\SharpDevelop Projects\Game_Test\Game_Test\Ресурсы\коробка.png";
        
        GameInterface gameinterface;
        Settings settings;
        Thread gameplay;
        bool flag = false;
        
        public MainForm()
        {
            //
            // The InitializeComponent() call is required for Windows Forms designer support.
            //
            InitializeComponent();
            gameinterface = new GameInterface();
            settings = new Settings();
            this.Controls.Add(gameinterface);
            this.AddOwnedForm(settings);
            gameinterface.Invalidate();
            //
            // TODO: Add constructor code after the InitializeComponent() call.
            //
        }
        
        void Button1Click(object sender, EventArgs e)
        {
            
            if (!flag)
            {
                try
                {
                    flag = true;
                    gameplay = new Thread(gameinterface.Invalidate);
                    gameplay.Start();
 
                }
                
                catch(Exception ex)
                {
                    MessageBox.Show(ex.Message,"Error",MessageBoxButtons.OK,MessageBoxIcon.Error);
                }
            }
            else
            {
                try
                {
                    flag = !flag;
                    gameplay.Abort(); ///
                    
                }
                catch(Exception ex)
                {
                    MessageBox.Show(ex.Message,"Error",MessageBoxButtons.OK,MessageBoxIcon.Error);
                }
            }
        }
    }
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.01.2017, 03:00
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Thread.Sleep() - для какого потока вызывается? (C#):

Как использовать Thread.Sleep(5000), ошибка: "Элемент "Thread" не существует в текущем контексте" - C#
я так понимаю, что Thread.Sleep(5000); это &quot;тормоз&quot; процесса выполенения программы на 5 сек? А как его правильно инициализировать и...

Thread.Sleep и lock - C#
Что будет если вызвать Thread.Sleep() внутри блока кода lock?

Thread.Sleep не работает - C#
Всем привет! Задача такая есть таймер который запускается каждый 30 сек и делает рассылку и уведомление Но когда наступает время (1 мин...

ProgressBar связать с thread.sleep - C#
как получать progressbar.Value в случае когда стоит задержка в 10 секунд и надо в прогресс бар показывать сколько секунд от 10 уже?или...

Аналог Thread.Sleep в Task - C#
Имеется пример который запускает пару потоков с задержкой. using System; using System.Collections.Generic; using System.Linq; using...

Странное поведение Thread.Sleep - C#
Забавно, уже не первый раз встречаю такую вещь: делаю движение контрола по форме в цикле (самостоятельно, или по нажатым клавишам). Чтобы...

9
Someone007
1875 / 1561 / 570
Регистрация: 09.05.2015
Сообщений: 3,901
Завершенные тесты: 1
30.01.2017, 03:07 #2
Thread.Sleep() - для потока, из которого произошел вызов. Предполагаю что GameInterfacePaint вызывается в основном потоке, соответственно и Thread.Sleep тоже.
0
NewNoob
6 / 10 / 0
Регистрация: 29.05.2015
Сообщений: 633
Завершенные тесты: 1
30.01.2017, 03:14  [ТС] #3
Someone007, ну,я так и понял,что из того,которого он был вызван. Но он был вызван в потоке gameplay - почему виснит основной поток?
0
Someone007
1875 / 1561 / 570
Регистрация: 09.05.2015
Сообщений: 3,901
Завершенные тесты: 1
30.01.2017, 03:43 #4
Цитата Сообщение от NewNoob Посмотреть сообщение
Но он был вызван в потоке gameplay
Значит это не так, что подтверждается вашим кодом. Вы вызываете метод Invalidate юзерконтрола в потоке gameplay, а событие Paint этого юзерконтрола все равно вызывается в основном потоке. Да и вообще не понятно зачем вам там Sleep нужен, его можно было бы и таймером простым заменить...
0
NewNoob
6 / 10 / 0
Регистрация: 29.05.2015
Сообщений: 633
Завершенные тесты: 1
30.01.2017, 04:04  [ТС] #5
Someone007, стоп,я событие вызываю-то разве не в новом потоке? Метод инвалидейт же вызывает событие пэйнт? Мне нужно форму постоянно перерисовывать. Если буду в основном потоке,то у меня тупо игра зависнет
0
TopLayer
720 / 543 / 208
Регистрация: 23.10.2016
Сообщений: 1,273
Завершенные тесты: 7
30.01.2017, 05:44 #6
NewNoob, во первых, нельзя вызывать методы контрола из потока, отличного от того, в котором он был создан.
https://msdn.microsoft.com/ru-ru/lib...кобезопасность
MSDNOnly the following members are thread safe: M:System.Windows.Forms.Control.BeginInvoke(System.Delegate), M:System.Windows.Forms.Control.EndInvoke(System.IAsyncResult), M:System.Windows.Forms.Control.Invoke(System.Delegate), P:System.Windows.Forms.Control.InvokeRequired, and M:System.Windows.Forms.Control.CreateGraphics if the handle for the control has already been created. Calling M:System.Windows.Forms.Control.CreateGraphics before the control's handle has been created on a background thread can cause illegal cross thread calls.

Во вторых, метод Control.Invalidate() не вызывает событие Paint, а помещает сообщение о невалидности поверхности контрола в очередь сообщений потока, в котором контрол был создан. Когда это сообщение будет обработано в основном потоке, тогда и сработает событие Paint.
0
NewNoob
6 / 10 / 0
Регистрация: 29.05.2015
Сообщений: 633
Завершенные тесты: 1
30.01.2017, 15:53  [ТС] #7
TopLayer, хм,как тогда поступить?
0
TopLayer
720 / 543 / 208
Регистрация: 23.10.2016
Сообщений: 1,273
Завершенные тесты: 7
30.01.2017, 16:44 #8
Во первых, можно так:
C#
1
gameinterface.BeginInvoke( (Action)(() => gameinterface.Invalidate()) );
Во вторых, никогда не используйте Thread.Sleep в основном потоке. Метод Paint должен рисовать текущее состояние, и только. Если надо что-то делать периодически, воспользуйтесь классом System.Windows.Forms.Timer. В его обработчике, меняйте состояние полей контрола, а затем вызывайте метод Invalidate().
0
NewNoob
6 / 10 / 0
Регистрация: 29.05.2015
Сообщений: 633
Завершенные тесты: 1
31.01.2017, 01:34  [ТС] #9
TopLayer, так у меня игра,т.е состояние ежесекундно будет меняться,если не быстрее

Добавлено через 12 минут
TopLayer, чё-то вообще впервые такую конструкцию вижу. Но мне ещё нужно обрывать этот метод по нажатию кнопки.

Добавлено через 3 минуты
Блин,прога просто зависает(
0
TopLayer
720 / 543 / 208
Регистрация: 23.10.2016
Сообщений: 1,273
Завершенные тесты: 7
31.01.2017, 09:10 #10
Цитата Сообщение от NewNoob Посмотреть сообщение
так у меня игра,т.е состояние ежесекундно будет меняться,если не быстрее
ну и пусть меняется.
Цитата Сообщение от NewNoob Посмотреть сообщение
Но мне ещё нужно обрывать этот метод по нажатию кнопки.
Не надо обрывать метод. Вообще не надо мыслить такими терминами. Если вы пишите проект с нуля, и у вас появляется Thread.Abort, знайте, вы наговнокодили. Вот, например, игра, в которой обновление происходит раз в несколько миллисикунд.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
class Game
{
    public PointF Center { get; }
    public float Radius { get; }
    public float BallRadius { get; }
    public float RevolvingFrequency { get; }
    private double _timeElapsed;
 
    private PointF BallCenter
    {
        get
        {
            double angle = RevolvingFrequency * _timeElapsed / 1000;
            var ballCenter = new PointF((float)(Center.X + Radius * Math.Cos(angle)), 
                (float)(Center.Y + Radius * Math.Sin(angle)));
            return ballCenter;
        }
    }
    
    public event Action<bool> GameOver;
    
    public void Click(float x, float y)
    {
        var ballCenter = BallCenter;
        if (Math.Pow(x - ballCenter.X, 2) + Math.Pow(y - ballCenter.Y, 2) <= Math.Pow(BallRadius, 2))
            GameOver?.Invoke(true);
        else
            GameOver?.Invoke(false);    
    }
    
    public void Update(TimeSpan dt)
    {
        _timeElapsed += dt.TotalMilliseconds;
    }
    
    public void Draw(Graphics g)
    {
        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
        var ballCenter = BallCenter;
        g.FillEllipse(Brushes.Red, ballCenter.X - BallRadius, ballCenter.Y - BallRadius, 2 * BallRadius, 2 * BallRadius);
    }
    
    public Game(PointF center, float radius, float frequency, float ballRadius)
    {
        Center = center;
        Radius = radius;
        RevolvingFrequency = frequency;
        BallRadius = ballRadius;
    }
    
    public void Restart()
    {
        _timeElapsed = 0;
    }
}
 
class MainForm: Form
{
    public MainForm()
    {
        DoubleBuffered = true;
        
        Cursor = Cursors.NoMove2D;
        
        Size = new Size(400, 400);
        
        var game = new Game(new PointF(200, 200), 100, 3f, 20);
        var lastUpdate = DateTime.Now;
 
        var updater = new System.Windows.Forms.Timer();
 
        game.GameOver += won =>
        {
            updater.Enabled = false;
            if (won)
            {
                MessageBox.Show("You win!");
            }
            else
            {
                MessageBox.Show("You loose!");
            }
            game.Restart();
            lastUpdate = DateTime.Now;
            updater.Enabled = true;
        };
 
        Click += (s, a) =>
        {
            var args = a as MouseEventArgs;
            game.Click(args.X, args.Y);
        };
    
        updater.Interval = 1;
        updater.Tick += (s, a) =>
        {
            var now = DateTime.Now;
            game.Update(now - lastUpdate);
            lastUpdate = now;
            Invalidate();
        };
 
        int count = 0;
 
        Paint += (s, a) =>
        {
            game.Draw(a.Graphics);
        };
        
        updater.Enabled = true;
    }
}
0
31.01.2017, 09:10
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.01.2017, 09:10
Привет! Вот еще темы с ответами:

Суммируется ли задержка двух Thread.Sleep - C#
Подскажите а Thread.Sleep суммируется или нет? 240000+60000=300000 или будет 240000 ? if (summa == 10) { ...

Более точная альтернатива Thread.Sleep(1) - C#
Как подсказывает мне гугл, Thread.Sleep - это зло во плоти, атата, руки оторвут, и т.д. Раньше проблем не было, пока не возникла...

В момент Thread.Sleep приложение не отвечает - C#
На форме два текстовых поля, из одного из них при нажатии на кнопку получаем значение. Затем нужно чтоб, через каждую секунду выводить (ето...

Кто врет : Thread.Sleep() или Stopwatch - C#
static void Main(string args){ bool proceed=false; int timeout = 1500; var sw = new...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru