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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> С# Многопоточность, использование потоков в Windows Form 
:(
    Опции темы
bobr
Дата 6.4.2008, 22:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Друзья, пишу текстовый редактор, хочется, чтобы в программе было несколько потоков.
1-ый поток - основной.
2-ой поток отслеживает позицию курсора (номер линии, на которой курсор находится) и выводит эту текущую позицию в некоторый textBox.

Пишу 2-ой поток таким образом: 
  
public class ThreadClass
        {
            
         
            public void Execute()
            {
                
                while (true)
                {
                   
                       textBox1.Text = richTextBox1.SelectionStart+" ";
                        Thread.Sleep(100);  
                }
            }

        }

а мне выдаются ошибки вида:

Error    7    Cannot access a nonstatic member of outer type 'TeEd.TeEdForm' via nested type 'TeEd.TeEdForm.ThreadClass'    E:\Documents and Settings\1\Рабочий стол\textEd1\TeEd\TeEdForm.cs    69    24    TeEd

Error    8    Cannot access a nonstatic member of outer type 'TeEd.TeEdForm' via nested type 'TeEd.TeEdForm.ThreadClass'    E:\Documents and Settings\1\Рабочий стол\textEd1\TeEd\TeEdForm.cs    69    40    TeEd


помогите разобраться, в чем дело. (если можно, напишите кусочек кода)

Заранее спасибо.
PM MAIL   Вверх
marcusmae
Дата 6.4.2008, 22:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


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

Репутация: 22
Всего: 39



bobr

до кусочка работающего кода, боюсь, сразу дело не дойдёт, поскольку ошибка состоит в том, что нестатические (то есть, экземплярные) поля textBox1 и richTextBox1, которые компилятор квалифицирует как относящиеся к outer (то есть, внешнему по отношению к ThreadClass) типу TeEd.TeEdForm, не могут быть употреблены в nested (то есть, вложенном) типе ThreadClass. Упрощая, та же самая ошибка содержится в следующем фрагменте :

Код

class A
{
    public int aNonStatticMember;

    class B // вложен в A
    {
        public B()
        {
            int a = aNonStaticMember; // та же самая ошибка
        }
    }
}




Это сообщение отредактировал(а) marcusmae - 6.4.2008, 22:19


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
bobr
Дата 7.4.2008, 00:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Друзья, если есть возможность, объясните в общих чертах, как справиться с такой задачей.

есть поле richTextBox, в нем пишут текст, нужно, чтобы параллельно с этим основным потоком работал другой, определяющий в какой строчке находится курсор, и выводящий эту информацию в какой-нибудь textBox.


marcusmae, спасибо за помощь, сделал эти классы "равнозначными", т.е. вынес один из другого, но прога не работает - выдается ошибка.

Заранее всем спасибо.
PM MAIL   Вверх
marcusmae
Дата 7.4.2008, 08:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


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

Репутация: 22
Всего: 39



Цитата(bobr @  7.4.2008,  00:06 Найти цитируемый пост)
есть поле richTextBox, в нем пишут текст, нужно, чтобы параллельно с этим основным потоком работал другой, определяющий в какой строчке находится курсор, и выводящий эту информацию в какой-нибудь textBox.


Ну смотрите : вот класс ManagedRichTextBox. Он расширяет стандартный RichTextBox функциональностью, связанной с потоками, определяя следующие элементы :
  •  параметр - временной интервал между двумя последовательными обновлениями координат
  •  собственно, сами TextBox-ы, в которые сбрасываются координаты курсора. Эта особенность - жёсткая привязка - связана с необходимостью переключения потоков при работе с элементами формы.
  •  поток-менеджер статуса координат курсора
  •  события "готовности" и "обновлённости" координат
Код

using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;

namespace WindowsApplication2
{
    // Defines a special rich text box extension with the threaded cursor managment
    // support.
    class ManagedRichTextBox : RichTextBox
    {
        public const int DefaultCursorUpdatingInterval = 500;
        private int cursorUpdatingInterval;
        /// <summary>
        /// The cursor coordinates updating interval.
        /// </summary>
        public int CursorUpdatingInterval { get { return this.cursorUpdatingInterval; } }
        
        public delegate void CursorsTextBoxesReadyDelegate(
            object sender, EventArgs e);
        public event CursorsTextBoxesReadyDelegate CursorsTextBoxesReady;

        public delegate void CursorsTextBoxesUpdatedDelegate(
            object sender, EventArgs e);
        public event CursorsTextBoxesUpdatedDelegate CursorsTextBoxesUpdated;

        private Thread cursorThread;
        /// <summary>
        /// Get the rich text box cursor thread.
        /// </summary>
        public Thread CursorThread { get { return this.cursorThread; } }

        private TextBox coordTextBoxX, coordTextBoxY;
        /// <summary>
        /// Get the X coordinate text box.
        /// </summary>
        public TextBox CoordTextBoxX { get { return this.coordTextBoxX; } }
        /// <summary>
        /// Get the Y coordinate text box.
        /// </summary>
        public TextBox CoordTextBoxY { get { return this.coordTextBoxY; } }

        // Initialize a new instance of the special rich text box extension with
        // the threaded cursor managment support.
        public ManagedRichTextBox(int cursorUpdatingInterval)
            : base()
        {
            this.cursorUpdatingInterval = cursorUpdatingInterval;
            this.cursorThread = new Thread(new ThreadStart(this.CursorThreadRunner));
        }

        // Initialize a new instance of the special rich text box extension with
        // the threaded cursor managment support.
        public ManagedRichTextBox()
            : this(ManagedRichTextBox.DefaultCursorUpdatingInterval)
        { }

        [DllImport("user32.dll")]
        private static extern IntPtr SendMessage(
            IntPtr hWnd, int msg, int wParam, int lParam);

        private void CursorThreadRunner()
        {
            // Create the X and Y coords text boxes.
            this.coordTextBoxX = new TextBox();
            this.coordTextBoxY = new TextBox();

            // Report the cursor text boxes are ready.
            if (this.CursorsTextBoxesReady != null)
                this.CursorsTextBoxesReady(this, new EventArgs());

            System.Timers.Timer timer = new System.Timers.Timer(
                this.cursorUpdatingInterval);
            timer.Elapsed += new System.Timers.ElapsedEventHandler(
                this.UpdateCoordinates);
            timer.Start();
        }

        void UpdateCoordinates(object sender, System.Timers.ElapsedEventArgs e)
        {
            this.Invoke(new CursorsTextBoxesUpdatedDelegate(
                this.UpdateCoordinates), this, new EventArgs());

            // Report the cursor text boxes were updated.
            if (this.CursorsTextBoxesUpdated != null)
                this.CursorsTextBoxesUpdated(this, new EventArgs());
        }

        void UpdateCoordinates(object sender, EventArgs e)
        {
            int
                y = (int)SendMessage(this.Handle, 201, -1, 0),
                x = (int)SendMessage(this.Handle, 176, 0, 0) & 0xffff;

            this.coordTextBoxX.Text = x.ToString();
            this.coordTextBoxY.Text = y.ToString();
        }
    }
}


Конструктор создаёт управляющий поток и связывает его с методом CursorThreadRunner. Поток не стартует немедленно, а "по требованию", если caller скомандовал :

Код

            // Start the cursor managing thread.
            this.managedRichTextBox1.CursorThread.Start();


Далее, в методе CursorThreadRunner происходит инициализация и старт таймера, который занимается отсчётом интервала, по прошествии которого периодически вызывает метод обновления координат курсора - UpdateCoordinates. Тот в свою очередь, как того требуют правила работы с формами, переключает поток и выполняет вычисление координат и обновление TextBox-ов. Само вычисление координат реализовано, через системный вызов посылки сообщения :

Код

        [DllImport("user32.dll")]
        public static extern IntPtr SendMessage(
            IntPtr hWnd, int msg, int wParam, int lParam);


следующим заклинанием :

Код

            int
                y = (int)SendMessage(this.Handle, 201, -1, 0) + 1,
                x = (int)SendMessage(this.Handle, 176, 0, 0) & 0xffff;


Чтобы сохранить интригу, данный код не вычисляет координаты в привычном понимании. Y - это индекс строки, но X - это абсолютный индекс символа - координата может быть из него получена различными способами.

Теперь, когда RichTextBox более-менее грамотно расширен, как того требует задача, мы можем воспользоваться им в какой-нибудь форме :

Код

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace WindowsApplication2
{
    public partial class Form1 : Form
    {
        private delegate void InitializeCursorManagmentDelegate(
            TextBox coordTextBoxX, TextBox coordTextBoxY);

        public Form1()
        {
            InitializeComponent();

            // Start the cursor managing thread.
            this.managedRichTextBox1.CursorThread.Start();
        }

        private void CursorTextBoxesReadyEventHandler(object sender, EventArgs e)
        {
            TextBox
                coordTextBoxX = this.managedRichTextBox1.CoordTextBoxX,
                coordTextBoxY = this.managedRichTextBox1.CoordTextBoxY;

            // 
            // coordTextBoxX
            // 
            coordTextBoxX.Location = new System.Drawing.Point(38, 232);
            coordTextBoxX.Name = "coordTextBoxX";
            coordTextBoxX.ReadOnly = true;
            coordTextBoxX.Size = new System.Drawing.Size(46, 20);
            coordTextBoxX.TabIndex = 1;
            // 
            // coordTextBoxY
            // 
            coordTextBoxY.Location = new System.Drawing.Point(116, 232);
            coordTextBoxY.Name = "coordTextBoxY";
            coordTextBoxY.ReadOnly = true;
            coordTextBoxY.Size = new System.Drawing.Size(46, 20);
            coordTextBoxY.TabIndex = 2;
            //
            // Add controls on the form.
            //
            this.Invoke(new InitializeCursorManagmentDelegate(
                this.InitializeCursorManagment), coordTextBoxX, coordTextBoxY);
        }

        private void InitializeCursorManagment(
            TextBox coordTextBoxX, TextBox coordTextBoxY)
        {
            this.Controls.Add(coordTextBoxY);
            this.Controls.Add(coordTextBoxX);
        }
    }
}


Всё, что здесь делается - это, по сути, инициализация, старт потока, затем доопределение необходимых свойств TextBox-ов и добавление их на форму (опять, с переключением потока через this.Invoke).

В качестве интервала обновления по умолчанию установлено 500 миллисекунд (0.5 сек), что довольно много : в тесте эта задержка слегка заметна при невысокой активности курсора.

user posted image

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

Это сообщение отредактировал(а) marcusmae - 7.4.2008, 08:37

Присоединённый файл ( Кол-во скачиваний: 7 )
Присоединённый файл  Project.rar 37,63 Kb


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
bobr
Дата 8.4.2008, 02:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



marcusmae, большое спасибо!!!
(читаю много литературы по Шарпу, но там в основном потоки рассмотрены на консольных примерах, здесь как раз проблем нет, у меня же проблема во взаимодействии классов...)

основная моя проблема, в том, как из класса, образующего второй поток обратиться к объекту (textBox) основного класса.
(понимаю, что вопрос дилетантский, но в C# делаю пока еще только первые шаги)

Если вам не трудно, напишите маленький пример такого вида:
дана простая форма с двумя textbox: tb1 и tb2.

и есть второй поток, который читает информацию из tb1 и записывает ее в tb2.

(на этом примере, думаю,у меня получится разобраться как класс потоков взаимодействует с объектами основного класса)


PM MAIL   Вверх
marcusmae
Дата 8.4.2008, 19:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


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

Репутация: 22
Всего: 39



Цитата(bobr @  8.4.2008,  02:12 Найти цитируемый пост)
основная моя проблема, в том, как из класса, образующего второй поток обратиться к объекту (textBox) основного класса.(понимаю, что вопрос дилетантский, но в C# делаю пока еще только первые шаги)


Нормальный вопрос! Чтобы экземпляр объекта был доступен, он должен быть либо членом класса, либо переданным извне параметром в скобочках. Последнее, думаю, сразу понятно, а стать членом класса необходимый объект может либо в результате соответствующего наследования :

Код

    class ManagedRichTextBox : RichTextBox
    {
         ...
    }


- все публичные (public) и защищённые (protected) элементы RichTextBox теперь есть и у ManagedRichTextBox,

либо явно, по Вашему желанию :

Код

    class ManagedRichTextBox : RichTextBox
    {
         ...
        private Thread cursorThread;
         ...
    }


Видно, что в предыдущем примере мне не пришлось никаким образом передавать textBox-ы в ManagedRichTextBox, потому что я создал их, во-первых, прямо в нём и, во-вторых, не на стороне основного потока, а на стороне вспомогательного :

Код

        private void CursorThreadRunner()
        {
            // Create the X and Y coords text boxes.
            this.coordTextBoxX = new TextBox();
            this.coordTextBoxY = new TextBox();
            ...
        }


Всё наоборот. Основная форма в начале своей жизни регистрируется на получение события о том, что вспомогательный поток сам создал textBox-ы :

Код

    this.managedRichTextBox1.CursorsTextBoxesReady += 
        new WindowsApplication2.ManagedRichTextBox.CursorsTextBoxesReadyDelegate(
        this.CursorTextBoxesReadyEventHandler);


- (см. в файле Form1.Designed.cs)

После чего она стартует вспомогательный поток :

Код

            // Start the cursor managing thread.
            this.managedRichTextBox1.CursorThread.Start();


Если у вспомогательного потока всё получилось, то после создания textBox-ов он разошлёт уведомления всем слушателям события CursorsTextBoxesReady :

Код

            // Report the cursor text boxes are ready.
            if (this.CursorsTextBoxesReady != null)
                this.CursorsTextBoxesReady(this, new EventArgs());


Среди слушателей обязательно окажется форма со своим обработчиком CursorTextBoxesReadyEventHandler, в котором подхватываются ссылки на textBox-ы и доопределяются всякие дизайнерские параметры. Всё это проделал всё тот же вспомогательный поток! Остаётся добавить textBox-ы на форму, чем, в силу устройства контролов, вспомогательный поток заниматься не может. Метод Invoke - это способ организации межпроцессорного взаимодействия между компонентами форм. При следующем вызове

Код

            this.Invoke(new InitializeCursorManagmentDelegate(
                this.InitializeCursorManagment), coordTextBoxX, coordTextBoxY);


процедура InitializeCursorManagment ставится на выполнение в очередь контрола this (то есть, самой формы), причём выполняется это не вспомогательным потоком, а тем, который создал форму, то есть основным.

Одновременно с этим вспомогательный поток ведёт свои дела. Он устанавливает таймер, срабатывающий с заданным интервалом. Зарегестрированный на событие таймера Elapsed обработчик 

Код

UpdateCoordinates(object sender, System.Timers.ElapsedEventArgs e)


вычисляет новые координаты курсора, опять же, через Invoke, поскольку обработчик сработал во вспомогательном потоке, но нужен Handle контрола ManagedRichTextBox, а ManagedRichTextBox создан основным потоком. Затем координаты сразу же попадают в textBox-ы.

А с событием CursorsTextBoxesUpdated вышла оплошность. Вообще говоря, при нынешнем расположении, оно возникает раньше, чем обновляются координаты. Стоит поместить его после обновления координат textBox-ов. Но это не очень важно, поскольку оно не используется.

Ну вот. Занимательный рассказ? smile 


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
marcusmae
Дата 8.4.2008, 20:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


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

Репутация: 22
Всего: 39



Цитата(bobr @  8.4.2008,  02:12 Найти цитируемый пост)
дана простая форма с двумя textbox: tb1 и tb2.и есть второй поток, который читает информацию из tb1 и записывает ее в tb2.


Окей, предыдущий вариант, возможно, на первый взгляд витееват, но у него есть и преимущества. Для разнообразия, поменяем схему : пусть оба textBox-а создаются основным потоком, а вспомогательный только играется с будильником.

Код

using System;
using System.Threading;
using System.Windows.Forms;

namespace WindowsApplication2
{
    /// <summary>
    /// Defines a textbox thread-"linked" to the other textbox.
    /// </summary>
    public class LinkedTextBox : TextBox
    {
        public delegate void LinkDelegate(object sender, EventArgs e);
        public event LinkDelegate StartedLink, UpdateLink, StoppedLink;

        public const int DefaultTimeoutInterval = 100;

        private int timeoutInterval;
        /// <summary>
        /// Get the timeout interval.
        /// </summary>
        public int TimeoutInterval { get { return this.timeoutInterval; } }

        private bool isStopping, isStopped;
        /// <summary>
        /// Get the value indicating if the linking thread is stopped.
        /// </summary>
        public bool IsStopped { get { return this.isStopped; } }

        private Control parentThreadControl;
        private Thread thread;
        private System.Timers.Timer timer;

        /// <summary>
        /// Start the linked textbox thread.
        /// </summary>
        public void ThreadStart(Control parentThreadControl)
        {
            this.parentThreadControl = parentThreadControl;
            this.thread = new Thread(new ThreadStart(this.ThreadProc));
            this.thread.Start();
            this.isStopping = false; this.isStopped = false;
            if (this.StartedLink != null)
                this.StartedLink(this, new EventArgs());
        }

        /// <summary>
        /// Stor the linked textbox thread.
        /// </summary>
        public void ThreadStop()
        {
            this.isStopping = true;
        }

        /// <summary>
        /// Initialize a new instance of the linked text box.
        /// </summary>
        /// <param name="textBox">The text box to link to.</param>
        public LinkedTextBox()
            : this(LinkedTextBox.DefaultTimeoutInterval)
        { }

        /// <summary>
        /// Initialize a new instance of the linked text box.
        /// </summary>
        /// <param name="textBox">The text box to link to.</param>
        /// <param name="timeoutInterval">The timeout interval.</param>
        public LinkedTextBox(int timeoutInterval)
            : base()
        {
            this.timeoutInterval = timeoutInterval;
        }

        private void ThreadProc()
        {
            this.timer = new System.Timers.Timer(
                this.timeoutInterval);
            this.timer.Elapsed += new System.Timers.ElapsedEventHandler(
                this.ThreadProcTimerElapsed);
            this.timer.Start();
        }

        private void ThreadProcUpdateLink(object sender, EventArgs e)
        {
            if (this.UpdateLink != null)
                this.UpdateLink(sender, e);

            if (this.isStopping)
            {
                // We are sure, the parent thread has exited the previous condition,
                // and is ready to stop processing.
                this.timer.Elapsed -= this.ThreadProcTimerElapsed;
                this.timer.Elapsed += new System.Timers.ElapsedEventHandler(
                    this.ThreadProcTimerStopped);
            }
        }

        private void ThreadProcTimerElapsed(object sender,
            System.Timers.ElapsedEventArgs e)
        {
            // Invoke the callback on the control's thread.
            this.parentThreadControl.Invoke(new LinkDelegate(
                this.ThreadProcUpdateLink), sender, e);
        }

        private void ThreadProcTimerStopped(object sender,
            System.Timers.ElapsedEventArgs e)
        {
            if (this.parentThreadControl.InvokeRequired)
                this.parentThreadControl.Invoke(
                    new System.Timers.ElapsedEventHandler(
                    this.ThreadProcTimerStopped), sender, e);
            else
            {
                this.timer.Stop();
                this.timer.Dispose();
                this.isStopped = true;
                if (this.StoppedLink != null)
                    this.StoppedLink(this, new EventArgs());
            }
        }
    }
}


Этот LinkedTextBox - это TextBox, расширенный необходимой функциональностью. Здесь явно присутствует передаваемый параметр (к Вашему вопросу), имеющий косвенное отношение к обоим textBox-ам : parentThreadControl.

Код

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace WindowsApplication2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            this.linkedTextBox1.UpdateLink += new LinkedTextBox.LinkDelegate(
                this.linkedTextBox1_UpdateLink);
            this.linkedTextBox1.ThreadStart(this);
        }

        protected override void WndProc(ref Message m)
        {
            // The hexademical message codes.
            int WM_SYSCOMMAND = System.Convert.ToInt32("112", 16);
            int SC_CLOSE = System.Convert.ToInt32("F060", 16);

            // Filter the needed message.
            if ((m.Msg == WM_SYSCOMMAND) && (m.WParam.ToInt32() == SC_CLOSE))
            {
                // нажата кнопка закрытия
                this.linkedTextBox1.StoppedLink += 
                    new LinkedTextBox.LinkDelegate(linkedTextBox1_StoppedLink);
                this.linkedTextBox1.ThreadStop();
                return;
            }

            // Call the base window proc for all other messages.
            base.WndProc(ref m);
        }

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

        private void linkedTextBox1_UpdateLink(object sender, EventArgs e)
        {
            List<char> symbols = new List<char>(this.textBox1.Text.ToCharArray());
            symbols.Reverse();
            this.linkedTextBox1.Text = new String(symbols.ToArray());
        }
    }
}


В данном варианте форма регистрируется на событие, связанное с обновлением textBox-ов и сама занимается их текстом. Что для этого нужно сделать на стороне вспомогательного потока? Во-первых, словить срабатывание таймера. А во-вторых, при сигнализации необходимости обновления textBox-ов переключиться в основной поток, чтобы созданные в нём textBox-ы могли быть изменены.

В отличие от предыдущего, этот вариант неудобен возможными проблемами при закрытии формы. Действительно, что будет, если форма вместе со своими textBox-ами уже начала освобождать ресурсы, а вспомогательный поток, как ни в чём не бывало, отправит туда предложение обновиться? = Будет вывалено исключение о попытке обратиться к объекту, который уже уничтожается (parentThreadControl, он же - экземпляр формы) smile Поэтому закрытие нужно аккуратно обставить. Вкратце, при нажатии крестика не происходит немедленного закрытия формы, а отправляется пожелание закончить работу вспомогательному потоку. После этого основной поток дожидается, пока вспомогательный, в силу своей асинхронности, "поймёт", что надо закругляться. О том, что он понял сообщает событием StoppedLink.

user posted image

Это сообщение отредактировал(а) marcusmae - 8.4.2008, 20:22

Присоединённый файл ( Кол-во скачиваний: 4 )
Присоединённый файл  Project2.rar 38,49 Kb


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
Alexandr507
Дата 22.2.2010, 18:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

Репутация: нет
Всего: -1



В продолжении темы о потоках в windows form

Разрабатываю приложение в котором нужен второй поток,  создал статический  метод
подскажите как туда передать всю форму

попробовал что то типа этого, не получается

Код

static void temp(Form1 xx) 
{
....         
}


        Thread computer = new Thread(temp(new Form1()));



PM MAIL   Вверх
KelTron
Дата 22.2.2010, 18:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 9
Всего: 38



Код

Thread computer = new Thread(temp);
computer.Start(new Form1());

static void temp(object xx) 
{
    var form = xx as Form1;       
}


Только учти, что ничего хорошего не выйдет, если ты будешь пытаться из этого потока обращатсья к гую.
http://msdn.microsoft.com/en-us/library/ms171728.aspx



--------------------
Тысячами незримых нитей обвивает тебя Закон. Разрубишь одну - преступник. Десять - смертник. Все - Бог.
Эвенгар Салладорский, основатель Школы Тьмы.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

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


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

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


 




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


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

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