Модераторы: Partizan, gambit

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Cross-Threading, Никак не догоню... 
:(
    Опции темы
VisualProgrammerNET
Дата 19.3.2006, 21:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Почётный халявщик
**


Профиль
Группа: Участник
Сообщений: 461
Регистрация: 30.10.2005
Где: Зеленоград

Репутация: 4
Всего: 6



Суть басни:

создаю поток а-ля
Код

Thread NewTrhread = new Thread(new ThreadStart(MyVoid));
NewThread.Start();


метод MyVoid в свою очередь обращается к Label на форме и меняет там значение Text. Но приложение работать не будет, ибо
Код

MyVoid()
{
this.label1.Text += SomeInt.ToString();
}

использовать нельзя.

Вопрос. Как это сделать? Пробовал совать в разные места кода lock {}, но так ничего и не добился... smile


--------------------
3 ГОДА НА user posted image 
PM MAIL ICQ   Вверх
mr.DUDA
Дата 19.3.2006, 22:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Есть такой метод, называется Control.Invoke... Принимает делегат на любой метод, и вызывает этот метод в GUI-потоке приложения. Есть ещё свойство Control.InvokeRequired - возвращает true, если вызвающий его код работает не в GUI-потоке.


--------------------
user posted image
PM MAIL WWW   Вверх
Wanderer2019
Дата 19.3.2006, 22:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 937
Регистрация: 3.12.2004
Где: Санкт-Петербург/П рага

Репутация: 7
Всего: 17



тоже пытался разобраться. Особенно на 2005 вообще со всем этим делом жесть!
Там появился какой то инструмент работы с потоками. Как работает тоже не понял.
Но на первый взгляд так делать надо так. Напрямую работать с контролами нельзя.
Необходимо работать через дополнительные функции. Т.е. из потока вызываем функцию,
которая в свою очередь обращается к свойствам контрола.

Вообщем присоединяюсь к вопросу =)

Хотя в 2003 вышеописанный код должен сработать.
Добавлено @ 22:48
mr.DUDA,

smile
PM ICQ MSN   Вверх
Exception
Дата 19.3.2006, 22:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 4525
Регистрация: 26.12.2004

Репутация: 29
Всего: 186



mr.DUDA дело говорит.
PM   Вверх
VisualProgrammerNET
Дата 19.3.2006, 22:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Почётный халявщик
**


Профиль
Группа: Участник
Сообщений: 461
Регистрация: 30.10.2005
Где: Зеленоград

Репутация: 4
Всего: 6



Я понимаю, что дело, но smile smile


--------------------
3 ГОДА НА user posted image 
PM MAIL ICQ   Вверх
Exception
Дата 19.3.2006, 23:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 4525
Регистрация: 26.12.2004

Репутация: 29
Всего: 186



1. Проверяй значение Control.InvokeRequired
2. Если false, можешь обращаться к свойствам напрямую
3. Если true, передаешь методу анонимный делегат, меняющий значение
Примерно выглядит так:
Код
if (!myTextBox.InvokeRequired)
{
    MyTextBox.Text += "1";
}
else
{
    MyTextBox.Invoke(
        new delegate()
            {MyTextBox.Text += "1";}
    );
}

PM   Вверх
VisualProgrammerNET
Дата 19.3.2006, 23:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Почётный халявщик
**


Профиль
Группа: Участник
Сообщений: 461
Регистрация: 30.10.2005
Где: Зеленоград

Репутация: 4
Всего: 6



Эк как всё хитро задумано... smile


--------------------
3 ГОДА НА user posted image 
PM MAIL ICQ   Вверх
mr.DUDA
Дата 20.3.2006, 10:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Exception, жжош smile

В 2003-й лямбда-функций нет, поэтому там будет вот так:
Код
        void ChangeText(string newText)
        {
            this.Text = newText;
        }

        delegate void ChangeTextMethodDelegate(string arg);

        void OtherThread()
        {
            if (this.InvokeRequired)
                this.Invoke(new ChangeTextMethodDelegate(this.ChangeText), "New text");
            else
                this.ChangeText("New text");
        }



--------------------
user posted image
PM MAIL WWW   Вверх
VisualProgrammerNET
Дата 2.4.2006, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Почётный халявщик
**


Профиль
Группа: Участник
Сообщений: 461
Регистрация: 30.10.2005
Где: Зеленоград

Репутация: 4
Всего: 6



Продолжение басни.

А что если есть некий класс, например, рисующий кружочек. smile По нажатию кнопки на форме, рисуется этот кружочек. В классе есть метод DoAction(), который делает всякое с кружочком. Так вот, мне надо, чтобы этот DoAction() выполнялся бесконечно в отдельном потоке. Бесконечный цикл я сделал, но метод не выполняется.

Код

Thread NewTrhread = new Thread(new ThreadStart(MyVoid));    
NewThread.Start();
MyVoid()    
{
bool finalize = false;
do
{
foreach (Creat c in ListObjects.ListCreat)
{
c.DoAction();
}
this.Invalidate();
}
while (!finalize);
}


При дебагге (ставил брейкпойнт на c.DoAction();), ход приложения запарывается как раз на этой строке. Без ошибок, без всего. Просто ничего не происходит с кружочками... Но Invalidate выполняется. В чём беда?

Это сообщение отредактировал(а) VisualProgrammerNET - 2.4.2006, 13:53


--------------------
3 ГОДА НА user posted image 
PM MAIL ICQ   Вверх
Exception
Дата 2.4.2006, 14:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 4525
Регистрация: 26.12.2004

Репутация: 29
Всего: 186



Можно все-таки код посмотреть полностью? Мало что понятно из этого куска.
PM   Вверх
VisualProgrammerNET
Дата 2.4.2006, 14:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Почётный халявщик
**


Профиль
Группа: Участник
Сообщений: 461
Регистрация: 30.10.2005
Где: Зеленоград

Репутация: 4
Всего: 6



Ммм... ща постараюсь выдрать то, что относится к этой части программы...

Собсна, это класс-кружочек
Код

public abstract class Creat : NonStatic, IActionable, IDrawable
    {
        #region Global Vars
        protected int MyNumber; //Идентификационный номер Креата
        protected string MyName; //Имя Креата
        protected DateTime MyBornTime; //Время рождения Креата
        protected Control MyLocation; //Местоположение Креата
        protected internal Action MyAction; //Следующее запланированное действие для Креата
        protected internal string MyActionString; //Действие Креата в текстовом виде
        #endregion

        #region Other Vars
        public void Drawable() { } //Реализация интерфейса. Ничего не делает, служит указателем на то, что объект надо перерисовывать.
        protected internal enum Action //Всевозможные действия всех типов креатов
        {
            think,
            gotopoint,            
        }
        #endregion

        #region Methods
        public override void DrawMe(Graphics g, SmoothingMode quality, System.Drawing.Text.TextRenderingHint text) //Перерисовывает креата на контроле. Этот метод надо вызывать из OnPaint. 
        {
            SolidBrush b = new SolidBrush(Color.Blue);
            g.SmoothingMode = quality;
            g.TextRenderingHint = text;            
            g.FillEllipse(b, this.x, this.y, Creat_Size_Adult, Creat_Size_Adult);
            DrawHUD(g);
            b.Dispose();
        }

        protected void DrawHUD(Graphics g) //Вспомогательный метод, отображает информацию о Креате.
        {
            Color c = Color.FromArgb(255, Color.Black);
            SolidBrush b = new SolidBrush(c);
            g.DrawString(this.MyName, new Font("Trebuchet MS", 8), b, this.x, this.y - 15);
            g.DrawString(this.MyActionString, new Font("Trebuchet MS", 8), b, this.x, this.y + Creat_Size_Adult);
            b.Dispose();
        }

        public void DoAction() //Выполняет следующее запланированное действие креата 
        {
            this.MeDoAction(this.MyAction);
        }

        protected abstract void MeDoAction(Action a); //Обработка текущего действия. Реализуется по-разному у разных типов Креатов.
        #endregion        
    }

    public sealed class CreatManAdult : Creat
    {
        #region Constructors

        public CreatManAdult(float x, float y, string name, Control location)
        {
            this.x = x;
            this.y = y;
            this.MyName = name;
            this.MyBornTime = DateTime.Now;
            this.MyLocation = location;
            this.MyNumber = ObjectList.List_Creat.Count + 1;
            this.MyAction = Action.think;
            ListMeUp(this);
            ObjectList.List_Creat.Add(this);
            location.Invalidate(); //!Не забудь перегрузить метод OnPaint контрола, вызвав DrawMe креата!
        }
        public CreatManAdult(Control location)
        {
            new CreatManAdult(0, 0, "Unnamed", location);
        }
        public CreatManAdult(float x, float y, Control location)
        {
            new CreatManAdult(x, y, "Unnamed", location);
        }
        public CreatManAdult(string name, Control location)
        {
            new CreatManAdult(0, 0, name, location);
        }

        #endregion

        #region Vars
        private int Counter = 0; //Счётчик
        private Random rand = new Random(DateTime.Now.Millisecond);
        #endregion

        #region Do Action
        protected override void MeDoAction(Action a) //Обработчик действия, выполняемого Креатом
        {
            switch (a)
            {
                #region Action.think
                case Action.think:
                    this.MyActionString = "Думает";
                    break;
                #endregion
                    //
                #region Action.gotopoint
                case Action.gotopoint:
                    MovingProcessor mp = new MovingProcessor(this);
                    mp.GoToPoint(200, 200);
                    break;
                #endregion
            }
        }
        #endregion

        // ///////////////////////////////////////////////
        private class MovingProcessor
        {
            private Creat obj;

            public MovingProcessor(Creat creat)
            {
                this.obj = creat;
            }

            public void GoToPoint(float x, float y)
            {
                obj.MyActionString = "Идёт";
            }
        }
    
    }


Там ещё многое нуждается в доработке, да...
----------------------
Вот код главной формы (управляющей)
Код

public partial class MainForm : Form
    {
        private Location1 l1;
        LifeConfig lc = new LifeConfig();
        public static List<LocationForm> Locations = new List<LocationForm>();
        Thread ActionThread;
        

        public MainForm()
        {
            InitializeComponent();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            
            l1 = new Location1();
            l1.Show();
            Locations.Add(l1);
            Preload();
            ActionThread = new Thread(new ThreadStart(this.LifeNext));
            ActionThread.Start();
        }   

        private void button1_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            CreatManAdult cma = new CreatManAdult(200, 200, "Billy", l1);
        }

        private void button5_Click(object sender, EventArgs e)
        {
            if (!lc.Focused)
            {                
                lc.Show();
                lc.Focus();
            }
            else
                lc.Focus();
        }

        private void Preload()
        {
            SmoothingMode gfxquality;
            System.Drawing.Text.TextRenderingHint textquality;

            //Load Settings//
            try
            {
                FileInfo fi = new FileInfo(AppDomain.CurrentDomain.BaseDirectory + "\\Storage\\Settings.lss");
                StreamReader sr = fi.OpenText();
                sr.ReadLine();
                sr.ReadLine();
                int a = Int32.Parse(sr.ReadLine().Substring(11, 1));
                int b = Int32.Parse(sr.ReadLine().Substring(12, 1));
                switch (a)
                {
                    case 0:
                        gfxquality = SmoothingMode.Default;
                        break;
                    case 1:
                        gfxquality = SmoothingMode.HighSpeed;
                        break;
                    case 2:
                        gfxquality = SmoothingMode.AntiAlias;
                        break;
                    case 3:
                        gfxquality = SmoothingMode.HighQuality;
                        break;
                    default:
                        gfxquality = SmoothingMode.Default;
                        break;
                }
                switch (b)
                {
                    case 0:
                        textquality = System.Drawing.Text.TextRenderingHint.SystemDefault;
                        break;
                    case 1:
                        textquality = System.Drawing.Text.TextRenderingHint.AntiAlias;
                        break;
                    case 2:
                        textquality = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
                        break;
                    case 3:
                        textquality = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
                        break;
                    default:
                        textquality = System.Drawing.Text.TextRenderingHint.SystemDefault;
                        break;
                }
                foreach (LocationForm lf in MainForm.Locations)
                {
                    lf.gfxquality = gfxquality;
                    lf.textquality = textquality;
                }
            }
            catch { }
        }

        private delegate void ReDrawDelegate();
        private void ReDraw()
        {
            this.Invalidate();
        }

        private void LifeNext()
        {       
            bool finalize = false;
            do
            {
                foreach (NonStatic ns in ObjectList.List_NonStaticObjects)
                {
                    ns.DoAction();
                }
                this.Invoke(new ReDrawDelegate(ReDraw));
                
                Thread.Sleep(50);
            }
            while (!finalize);
            
        }

    }

    public class LocationForm : Form
    {
        protected internal SmoothingMode gfxquality;
        protected internal System.Drawing.Text.TextRenderingHint textquality;
    }

----------------------
А это LocationForm, где отрисовывается и двигается классы-кружочки
Код

public partial class Location1 : LocationForm
    {        

        public Location1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            PlayableZone pz = new PlayableZone(this);
            Wall w = new Wall(400, 100, 400, 500, this);            
        }       

        private void timer1_Tick(object sender, EventArgs e)
        {
            
        }       

        private void Location1_FormClosing(object sender, FormClosingEventArgs e)
        {
            e.Cancel = true;
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            foreach (LifeObject lo in ObjectList.List_LifeObjects)
            {
                if (lo is IDrawable)
                {
                    lo.DrawMe(e.Graphics, gfxquality, textquality);
                }
            }            
        }

        private void Location1_MouseClick(object sender, MouseEventArgs e)
        {
            
        }        
    }


Много мусора в коде, да =) Ещё только в начале пути...


--------------------
3 ГОДА НА user posted image 
PM MAIL ICQ   Вверх
VisualProgrammerNET
Дата 3.4.2006, 00:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Почётный халявщик
**


Профиль
Группа: Участник
Сообщений: 461
Регистрация: 30.10.2005
Где: Зеленоград

Репутация: 4
Всего: 6



Неужели совсем ничего нельзя сделать с этой штукой? smile


--------------------
3 ГОДА НА user posted image 
PM MAIL ICQ   Вверх
mr.DUDA
Дата 3.4.2006, 22:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



VisualProgrammerNET, маньяк убийц0 smile


--------------------
user posted image
PM MAIL WWW   Вверх
VisualProgrammerNET
Дата 4.4.2006, 12:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Почётный халявщик
**


Профиль
Группа: Участник
Сообщений: 461
Регистрация: 30.10.2005
Где: Зеленоград

Репутация: 4
Всего: 6



smile

Это да, но что с проблемой делать? smile

Можно ли как-нибудь сделать, чтобы класс поддерживал метод Invoke? smile


--------------------
3 ГОДА НА user posted image 
PM MAIL ICQ   Вверх
Exception
Дата 4.4.2006, 17:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 4525
Регистрация: 26.12.2004

Репутация: 29
Всего: 186



Чего-то у меня совсем голова не варит. Можно ещё раз разжевать проблему и чуточку поконкретнее код (а мусора и правда много)..
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0931 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.