WebBrowser - пользовательский интерфейс тормозит

Язык Visual Basic на платформе .NET.

Модераторы: Ramzes, Sebas

COSANOSTRA
Начинающий
Начинающий
 
Сообщения: 17
Зарегистрирован: 02.10.2014 (Чт) 20:02

WebBrowser - пользовательский интерфейс тормозит

Сообщение COSANOSTRA » 03.10.2014 (Пт) 8:36

Здравствуйте, хочу написать клиент для онлайн игры, для этого использую компонент webbrowser. И сразу появилась проблема, при загрузке игры WebBrowser1.Navigate("http://tankionline.com/battle-ru.html#/server=RU13") пользовательский интерфейс зависает (форма таймер и т.д) Как обрабатывать компонент webbrowser в отдельном потоке? Поток создаю так

Код: Выделить всё
Imports System.Threading

Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
   Dim поток As New Thread(AddressOf поток1)
   поток.IsBackground = True     
   поток.Start()       
End Sub

Sub поток()
        ------
End Sub
   
End Class


Если есть вариант без использования потоков, буду только рад.
Последний раз редактировалось COSANOSTRA 06.10.2014 (Пн) 6:17, всего редактировалось 2 раз(а).

COSANOSTRA
Начинающий
Начинающий
 
Сообщения: 17
Зарегистрирован: 02.10.2014 (Чт) 20:02

Re: WebBrowser в новый поток

Сообщение COSANOSTRA » 04.10.2014 (Сб) 8:49

Передавать постоянно фокус форме не вариант, управление в игре теряется

COSANOSTRA
Начинающий
Начинающий
 
Сообщения: 17
Зарегистрирован: 02.10.2014 (Чт) 20:02

Re: WebBrowser в новый поток

Сообщение COSANOSTRA » 05.10.2014 (Вс) 5:43

Теперь я совсем запутался.. кидаю на форму лейбл и компонент веб браузер, создаю таймер в новом потоке

Код: Выделить всё
Public Class Form1
    Private tTimer As System.Timers.Timer
    Private a As Integer
   
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        tTimer = New System.Timers.Timer()
        tTimer.Enabled = True
        tTimer.Interval = 100
        AddHandler tTimer.Elapsed, AddressOf Timer5
        tTimer.AutoReset = True
        tTimer.Start()

        WebBrowser1.Navigate("http://tankionline.com/battle-ru.html#/server=RU13")
    End Sub
   
    Private Sub Timer5(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs)
        a = a + 1
        Me.Invoke(New Action(AddressOf SetLabel))
    End Sub
   
    Private Sub SetLabel()
        Label1.Text = a
    End Sub
End Class


После запуска игры лейбл замирает.. почему? Ведь таймер обновляющий его находится в другом потоке… Помогите разобраться..

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 05.10.2014 (Вс) 11:43

Потому что WebBrowser работает в UI'ном потоке.

COSANOSTRA
Начинающий
Начинающий
 
Сообщения: 17
Зарегистрирован: 02.10.2014 (Чт) 20:02

Re: WebBrowser в новый поток

Сообщение COSANOSTRA » 05.10.2014 (Вс) 13:19

То есть, если я правильно понял, компонент WebBrowser может работать только в потоке пользовательского интерфейса и нигде иначе, тогда как это реализовано в том же Internet Explorer.. ведь там интерфейс пользователя не зависает

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 06.10.2014 (Пн) 0:12

COSANOSTRA писал(а):компонент WebBrowser может работать только в потоке пользовательского интерфейса и нигде иначе

Не факт.
И не компонент, а .NET'овская обёртка.
И не в UI'ном, а в том, в каком создан, скорее всего.

COSANOSTRA
Начинающий
Начинающий
 
Сообщения: 17
Зарегистрирован: 02.10.2014 (Чт) 20:02

Re: WebBrowser в новый поток

Сообщение COSANOSTRA » 06.10.2014 (Пн) 6:12

Создаю поток, присваиваю ему состояние SetApartmentState, создаю в нем webbrowser. Кидаю на форму таймер и лейбл

Код: Выделить всё
Imports System.Threading
Public Class Form1
    Friend web1 As System.Windows.Forms.WebBrowser

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim поток As New Thread(AddressOf поток1)

        поток.SetApartmentState(ApartmentState.STA)
        поток.IsBackground = True
        поток.Start()
    End Sub

    Sub поток1()
        web1 = New WebBrowser
        Me.Invoke(Sub()
                      Me.Controls.Add(web1)
                      web1.Height = 600
                      web1.Width = 1024
                      web1.Navigate("http://tankionline.com/battle-ru.html#/server=RU13")
                  End Sub)
    End Sub


    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        Label1.Text = TimeString
    End Sub
End Class


как интерфейс тормозил, так и тормозит. Объясните пожалуйста доступным языком что я делаю не так и как добиться желаемого результата

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 06.10.2014 (Пн) 11:48

Мне кажется, или STA-поток может быть только один?

COSANOSTRA
Начинающий
Начинающий
 
Сообщения: 17
Зарегистрирован: 02.10.2014 (Чт) 20:02

Re: WebBrowser - пользовательский интерфейс тормозит

Сообщение COSANOSTRA » 08.10.2014 (Ср) 12:28

Добился желаемого результата создавая копию второй формы в новом потоке, получается как вкладки у браузера.. все что происходит на вкладке никак не влияет на основную форму, даже если она зависнет. Но теперь при работе отображаются две формы, вопрос : как поместить форму 2 на форму 1

Код: Выделить всё
Imports System.Threading
Public Class Form1

    Dim forms As Form2
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim поток As New Thread(AddressOf поток1)

        поток.SetApartmentState(ApartmentState.STA)
        поток.IsBackground = True
        поток.Start()
    End Sub
    Sub поток1()
        forms = New Form2
       
        forms.WebBrowser1.Navigate("http://tankionline.com/battle-ru.html#/server=RU13")
        forms.ShowDialog()
    End Sub
    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        Label1.Text = TimeString
    End Sub

End Class
Вложения
WindowsApplication2.rar
(55.66 Кб) Скачиваний: 492

COSANOSTRA
Начинающий
Начинающий
 
Сообщения: 17
Зарегистрирован: 02.10.2014 (Чт) 20:02

Re: WebBrowser - пользовательский интерфейс тормозит

Сообщение COSANOSTRA » 08.10.2014 (Ср) 14:21

Пытаюсь так.. в свойствах формы Form1.IsMdiContainer = True, в потоке Me.Invoke(New Action(AddressOf SetForm))

Код: Выделить всё
Private Sub SetForm()
   forms.MdiParent = Me
End Sub


получаю:

Невозможно получить дескриптор окна для элемента управления 'WebBrowser'. Элементы управления ActiveX, не базирующиеся на окнах, не поддерживаются.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 08.10.2014 (Ср) 14:35

Попробуй Parent без MDI.

COSANOSTRA
Начинающий
Начинающий
 
Сообщения: 17
Зарегистрирован: 02.10.2014 (Чт) 20:02

Re: WebBrowser - пользовательский интерфейс тормозит

Сообщение COSANOSTRA » 08.10.2014 (Ср) 14:55

Попробуй Parent без MDI.


получаю:

Элемент верхнего уровня нельзя добавлять к элементу управления.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 08.10.2014 (Ср) 15:07

COSANOSTRA писал(а):Элемент верхнего уровня нельзя добавлять к элементу управления.

Ага, надо было TopLevel сначала убрать.
http://www.cyberforum.ru/vb-net/thread1071316.html#post5655271
Код: Выделить всё
  With New Form2
    .TopLevel = False
    .Parent = Owner
    .Show()
  End With
Но всё равно будет косяк с потоками, скорее всего. Для одной из форм. Так что, возможно, придётся воспользоваться WinApi, чтобы установить родителя.

COSANOSTRA
Начинающий
Начинающий
 
Сообщения: 17
Зарегистрирован: 02.10.2014 (Чт) 20:02

Re: WebBrowser - пользовательский интерфейс тормозит

Сообщение COSANOSTRA » 08.10.2014 (Ср) 15:33

.TopLevel = False
.Parent = Owner
.Show()


Ругается на ShowDialog()

Форму, не являющуюся формой верхнего уровня, нельзя отобразить как модальное диалоговое окно. Удалите эту форму из всех родительских форм перед вызовом showDialog.

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

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 08.10.2014 (Ср) 15:35

Внимательнее что ли...

COSANOSTRA
Начинающий
Начинающий
 
Сообщения: 17
Зарегистрирован: 02.10.2014 (Чт) 20:02

Re: WebBrowser - пользовательский интерфейс тормозит

Сообщение COSANOSTRA » 09.10.2014 (Чт) 19:33

Не догоняю реально.. помещается форма2 на форму1 но она создается в потоке формы1.. если не затруднит покажи на моем примере как это реализовать

COSANOSTRA
Начинающий
Начинающий
 
Сообщения: 17
Зарегистрирован: 02.10.2014 (Чт) 20:02

Re: WebBrowser - пользовательский интерфейс тормозит

Сообщение COSANOSTRA » 10.10.2014 (Пт) 20:52

не получается даже через WinApi не могу вызвать SetParent(form2.Handle, me.Handle) получается формы должны быть созданы в одном потоке

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 11.10.2014 (Сб) 20:09

Для этого есть переменные. В SetPerent надо передавать две переменные. Или одну переменную и хендл текущей формы. А у тебя идёт обращение из текущего потока к свойству (Handle) формы, созданной в другом.
Не могу сейчас проверять - нет времени.

COSANOSTRA
Начинающий
Начинающий
 
Сообщения: 17
Зарегистрирован: 02.10.2014 (Чт) 20:02

Re: WebBrowser - пользовательский интерфейс тормозит

Сообщение COSANOSTRA » 12.10.2014 (Вс) 10:46

Не выходит, созданная форма закрывается и все.. ничего не происходит

Код: Выделить всё
Imports System.Threading
Imports System.Runtime.InteropServices

Public Class Form1
    <DllImport("User32", CharSet:=CharSet.Auto, ExactSpelling:=True)> _
    Public Shared Function SetParent(ByVal hWndChild As IntPtr, ByVal hWndParent As IntPtr) As IntPtr
    End Function

    Public ss As Integer
    Dim forms As Form2
   Sub поток1()
        forms = New Form2
        ss = forms.Handle
        forms.WebBrowser1.Navigate("http://tankionline.com/battle-ru.html#/server=RU13")
        forms.ShowDialog()
    End Sub
    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        Label1.Text = TimeString
    End Sub
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim поток As New Thread(AddressOf поток1)

        поток.SetApartmentState(ApartmentState.STA)
        поток.IsBackground = True
        поток.Start()
    End Sub
    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        SetParent(ss, Me.Handle)
    End Sub
End Class

COSANOSTRA
Начинающий
Начинающий
 
Сообщения: 17
Зарегистрирован: 02.10.2014 (Чт) 20:02

Re: WebBrowser - пользовательский интерфейс тормозит

Сообщение COSANOSTRA » 14.10.2014 (Вт) 5:14

Разобрался, работает, форма 2 помещена в форму 1 работает в отдельном потоке.

форма 1
Код: Выделить всё
Imports System.Threading

Public Class Form1
    Sub поток1()
        forms = New Form2
        forms.WebBrowser1.Navigate("http://tankionline.com/battle-ru.html#/server=RU13")
        forms.ShowDialog()
    End Sub
    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        Label1.Text = TimeString
    End Sub
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim поток As New Thread(AddressOf поток1)

        поток.SetApartmentState(ApartmentState.STA)
        поток.IsBackground = True
        поток.Start()
    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ss = Me.Handle
    End Sub
End Class


форма 2
Код: Выделить всё
Public Class Form2
    Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        SetParent(forms.Handle, ss)
    End Sub
End Class


модуль
Код: Выделить всё
Imports System.Runtime.InteropServices
Module Module1
    Public ss As Integer
    Public forms As Form2
    <DllImport("User32", CharSet:=CharSet.Auto, ExactSpelling:=True)> _
    Public Function SetParent(ByVal hWndChild As IntPtr, ByVal hWndParent As IntPtr) As IntPtr
    End Function
End Module

COSANOSTRA
Начинающий
Начинающий
 
Сообщения: 17
Зарегистрирован: 02.10.2014 (Чт) 20:02

Re: WebBrowser - пользовательский интерфейс тормозит

Сообщение COSANOSTRA » 14.10.2014 (Вт) 6:14

И еще пару нюансов:
1 как сделать формы единым окном? то есть сейчас фокус у каждой формы свой
2 на форме 1 находится лейбл, как его поместить на передний план, сейчас его перекрывает форма 2

COSANOSTRA
Начинающий
Начинающий
 
Сообщения: 17
Зарегистрирован: 02.10.2014 (Чт) 20:02

Re: WebBrowser - пользовательский интерфейс тормозит

Сообщение COSANOSTRA » 05.11.2014 (Ср) 12:54

Возможно кому ни будь пригодится.. визуально форма с экземпляром webbrowser, который работает с своем потоке никак не влияя на пользовательский интерфейс

Form1
Код: Выделить всё
Imports System.Threading

Public Class frmClient
    Dim NUI As Thread
    Dim URL As String = "https://www.google.ru"
    Dim NUI_Form As new Form2

    Private Sub NUI_Creat()
        If NUI IsNot Nothing Then
            NUI.Abort()
        End If
        NUI = New Thread(AddressOf NUI_Thread)
        With NUI
            .SetApartmentState(ApartmentState.STA)
            .IsBackground = True
            .Start()
        End With
    End Sub
    Private Sub NUI_Thread()
        NUI_Form = New Form2
        NUI_Form.WebBrowser1.Hide()
        NUI_Form.ShowDialog()
    End Sub
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
        Client_Handle = Me.Handle
    End Sub
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        NUI_Creat()
    End Sub
    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        NUI_Form.Invoke(Sub() NUI_Form.WebBrowser1.Hide())
    End Sub
    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
        NUI_Form.Invoke(Sub() NUI_Form.WebBrowser1.Show())
    End Sub
    Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
        NUI_Form.Invoke(Sub() NUI_Form.WebBrowser1.Navigate(URL))
    End Sub

End Class



Form2
Код: Выделить всё
Imports System.Runtime.InteropServices
Public Class Form2

    Const WS_CHILD = &H40000000
    Protected Overrides ReadOnly Property CreateParams() As CreateParams
        Get
            Dim CP As CreateParams = MyBase.CreateParams
            CP.Style = WS_CHILD
            Return CP
        End Get
    End Property

    <DllImport("User32", CharSet:=CharSet.Auto, ExactSpelling:=True)>
    Public Shared Function SetParent(ByVal hWndChild As IntPtr, ByVal hWndParent As IntPtr) As IntPtr
    End Function


    Private Sub Form2_Load(sender As Object, e As EventArgs) Handles Me.Load
        SetParent(Me.Handle, Client_Handle)
        Me.SendToBack()
        Me.Height = Form1.Height : Me.Width = Form1.Width
    End Sub

End Class


переменную Public Client_Handle As Integer объявить в модуле, объявляя ее в форме, по непонятным причинам SetParent не работает


Вернуться в Visual Basic .NET

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 19

    TopList