none
Создание потоков и форм для вывода данных из этих потоков RRS feed

  • Вопрос

  • Сделал следующее.

    Класс потока

    Public Class MyTestClass
    
     Private Id As String
    
     Private n As Integer
    
     Private _parentform As Form
    
    
    
     Public Property Name() As String
    
      Get
    
       Return Id
    
      End Get
    
      Set(ByVal value As String)
    
       Id = value
    
      End Set
    
     End Property
    
    
    
    
    
     Sub New(ByVal Name As String, ByRef mdi As Form)
    
      Id = Name
    
      n = 0
    
      _parentform = mdi
    
     End Sub
    
    
    
    
    
     Public Sub Worker_2()
    
      Dim _txtbox As TextBox
    
      Dim count As Integer
    
      Dim _id As String
    
      Dim _form As New Form()
    
      _form.MdiParent = _parentform
    
    
    
      _txtbox = New TextBox()
    
      _txtbox.Parent = _form
    
      _txtbox.Width = 200
    
    
    
      count = 0
    
      _id = Id
    
    
    
      _form.Show()
    
    
    
      While True
    
       _txtbox.Text = "I'm " & _id & " " & count.ToString
    
       _txtbox.Refresh()
    
       count = count + 1
    
      End While
    
    
    
     End Sub
    
    
    
    End Class
    
    

    Он создается в форме по кнопке

    Public Class main
    
    	Private My_first_Thread As Thread
    
    	Private Thread_Start As ThreadStart
    
    	Private FirstThread As New MyTestClass("First Thread", Me)
    
    
    
    	Private Sub ToolStripButton2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripButton2.Click
    
     
    
      		Thread_Start = New ThreadStart(AddressOf SecondThread.Worker_2)
    
      		my_first_thread = New Thread(Thread_Start)
    
      		my_first_thread.IsBackground = False
    
      		my_first_thread.Priority = ThreadPriority.Normal
    
      		my_first_thread.Start()
    
     End Sub
    
    

    Если делать так, как я привет в примере, то возникает ошибка доступа к объекту с другого потока. В принципе понятно почему.

    Вопрос такой:

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

    2) почему, если сфокусироваться на родительской форме, то форма, созданная потоком и ее элементы пер

    • Перемещено Abolmasov Dmitry 22 апреля 2011 г. 11:38 (От:Языки программирования)
    10 апреля 2011 г. 9:05

Ответы

  • Посмотрите сюда на 2-й странице 48 пост, может быть поможет. Здесь, правда голимый C#
    http://www.gotdotnet.ru/forums/2/129771/page-2/
    • Предложено в качестве ответа Maximys33 11 апреля 2011 г. 8:51
    • Помечено в качестве ответа Abolmasov Dmitry 20 апреля 2011 г. 11:00
    10 апреля 2011 г. 19:31
  • Сделать mdi форму в другом потоке не получится, т.к. контрол не может быть родителем для другого контрола не из того же потока. Будете получать исключение (Controls created on one thread cannot be parented to a control on a different thread.)

    Вообще создавать формы в разных потоков не рекомендуется. Весь GUI приложения должнен быть в одном главном потоке. А вот обработку какой-либо тяжелой логики уже стоит выносить в отдельные потоки (в вашем примере - цикл while, из-за него и перестает быть доступной форма и ее элементы).


    Для связи [mail]
    • Предложено в качестве ответа Abolmasov Dmitry 15 апреля 2011 г. 9:14
    • Помечено в качестве ответа Abolmasov Dmitry 20 апреля 2011 г. 11:00
    11 апреля 2011 г. 7:34

Все ответы

  • Посмотрите сюда на 2-й странице 48 пост, может быть поможет. Здесь, правда голимый C#
    http://www.gotdotnet.ru/forums/2/129771/page-2/
    • Предложено в качестве ответа Maximys33 11 апреля 2011 г. 8:51
    • Помечено в качестве ответа Abolmasov Dmitry 20 апреля 2011 г. 11:00
    10 апреля 2011 г. 19:31
  • Сделать mdi форму в другом потоке не получится, т.к. контрол не может быть родителем для другого контрола не из того же потока. Будете получать исключение (Controls created on one thread cannot be parented to a control on a different thread.)

    Вообще создавать формы в разных потоков не рекомендуется. Весь GUI приложения должнен быть в одном главном потоке. А вот обработку какой-либо тяжелой логики уже стоит выносить в отдельные потоки (в вашем примере - цикл while, из-за него и перестает быть доступной форма и ее элементы).


    Для связи [mail]
    • Предложено в качестве ответа Abolmasov Dmitry 15 апреля 2011 г. 9:14
    • Помечено в качестве ответа Abolmasov Dmitry 20 апреля 2011 г. 11:00
    11 апреля 2011 г. 7:34
  • Сам использую следующий код для передачи данных из одного потока в объект, созданный в другом потоке:

    #region Группа методов для передачи данных из одного потока в другой
            delegate void SetTextCallback(TextBox aaDateFromClients_textBox, FormLab2 aaformLab2, String text);
    
            private void SetText(TextBox aaDateFromClients_textBox, FormLab2 aaformLab2, String text)
            {
              if (aaDateFromClients_textBox.InvokeRequired)
              {
                SetTextCallback d = new SetTextCallback(SetText);
                text = text.Replace("\n", String.Empty);  //удаляем символ перехода на новую строку, чтобы информация отображалась более корректно
                if(text!="")
                  aaformLab2.Invoke(d, new object[] {aaDateFromClients_textBox, aaformLab2 , text + Environment.NewLine });
              }
              else
              {
                aaDateFromClients_textBox.Text += text;
              }
            }
    
            private void ThreadProcSafe(TextBox aDateFromClients_textBox, FormLab2 aformLab2, String str)
            {
              SetText(aDateFromClients_textBox, aformLab2, str);
            }
          #endregion
    
    
    Из программы вызываю метод ThreadProcSafe, где аргумент aDateFromClients_textBox является объектом, куда нужно вывести данные, aformLab2 - форма, на которой создан объект, str - строка, которую нужно вывести

    11 апреля 2011 г. 8:57
  • Ох, че то я понял, что моих любительских познаний в Си не хватает, чтобы код понять, особенно который по ссылке.

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

    Значит вопрос: почему форма, созданная в потоке, если в ней не работает никакой вычислительный процесс (в моем случае цикл), закрывается? Потому что отрабатывает процедура, которую я запускаю в потоке до конца и он прерывается?

    Ну и задача:

    У меня есть Класс, который содержит в себе "сервер", обрабатывающий некие поступающие в него данные. Обработка поступивших данных происходит периодически по вызову метода сервера из другого приложения. Этих серверов я хочу запускаеть несколько штук, но они не запускаются в отдельных потоках - поток отрабатывает процедуру запуска и завершается, потому что нет никакого вычислительного процесса в нем (точнее он периодический). Как быть?

    Мне нужно выводить для каждого такого потока с сервером данные в отдельную MDI - форму. Данные просто текстовые, но текстбоксов несколько. Посоветуйте, пожалуйста.

    20 апреля 2011 г. 14:01
  • Как же это Вы, батенька?
    С C# надо подружиться!

    Попробуем?

    1. Создать новый проект - Файл - Создать проект - Заполнить, что там просят.
        Выскакивает конструктор с формой, форма с заголовком Form1
    2. F7 -  Открывается лист Form1.cs с какой-то программой,
    3. Из программы http://www.gotdotnet.ru/forums/2/129771/page-2/ 
        из поста № 48, не спутайте, там несколько программ,
        скопировать начиная с 6 строки до конца,
    4. Заменить текст в Вашем проекте, начиная после строки namespace и до конца,
        скопированным текстом,
    5. Удалить нумерацию строк, утрясти соответствие фигурных скобок,
    6. Заменить MainForm на Form1 в двух местах - сразу после namespace и
        в следующей строке, 
    7. Добавить строчку using System.Threading;
        в начало программы, после строки  using System.Windows.Forms;
    8. В конструкторе, та форма которая выскочила при создании проекта,
        добавить кнопку. Для этого
        а. Активизировать конструктор
        б. Ctrl-Alt-X - появляется панель элементов,
        в. На этой панели мышкой зацепить Button и перетащить на форму,
        г. Активизировать кнопку button1,
        д. F4 - появляется окно свойств,
        е. Кликнуть на молнии в верхней части окна свойств - появляется окно событий,
        ж. Напротив события Click в пустую графу вписать  btNew_Click,
            это программа в тексте, которая запускается по нажатию на кнопку.
     9. Ctrl-Shift-S - сохранить куда положено
    10. F5 - запуск.

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

    С бейсиком как-нибудь сами разберетесь...

     



    20 апреля 2011 г. 15:49
  • Спасибо за подробное объяснение, но как из куска кода приложение сделать я знаю, я в суть кода не совсем въехал и при попытке переписать на бейси у меня сложности с:

    protected override void Dispose(bool disposing) {if (disposing) {if (components!=null) components.Dispose();} base.Dispose(disposing);} и с if ( TimerEvent != null ) TimerEvent(); Не смог вкурить как на вб переписать.

    20 апреля 2011 г. 16:18
  • Первое - стандартный Dispose-метод, формируемый автоматом при создании проекта, какой-то аналог наверное существует и в бейсике.

    Второе - какой-то аналог на бейсике должен быть, надо искать.

    20 апреля 2011 г. 16:59