Skip to main content
gamedev.net
🔒 Locked 🎮 Unity

VB2005 Threading

Started by ukdeveloper 4 replies 1.4k views
Original Post
ukdeveloper
ukdeveloper
Hi folks, Just been getting back into VB a bit for RAD (I used VB6, but it was a few years ago now). I'm using MSVS 2005 Professional (downloaded off MSDNAA). I found an example on MS Help and Support about implementing threads (find it here), and my code now looks like this:

Imports System.Threading

Public Class Form1

    Private trd As Thread

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        trd = New Thread(AddressOf ThreadTask)
        trd.IsBackground = True
        trd.Start()

    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        MessageBox.Show("This is the main thread")
    End Sub

    Private Sub ThreadTask()

        Dim stp As Integer
        Dim newval As Integer
        Dim rnd As New Random()

        Do

            stp = ProgressBar1.Step * rnd.Next(-1, 2)
            newval = ProgressBar1.Value + stp
            If newval > ProgressBar1.Maximum Then
                newval = ProgressBar1.Maximum
            ElseIf newval < ProgressBar1.Minimum Then
                newval = ProgressBar1.Minimum
            End If

            ProgressBar1.Value = newval

            Thread.Sleep(100)

        Loop
    End Sub
End Class

I can't see any obvious difference between this and the MS original. Problem is, when I run it, it flags up
ProgressBar1.Value = newval
and throws an InvalidOperationException, with the reason "Cross-thread operation not valid: Control 'ProgressBar1' accessed from a thread other than the thread it was created on." I've got no idea what the hell that's all about, this code is copied straight from MS. Is there some configuration option I'm missing here? Thanks in advance, ukdeveloper.
MrEvil
MrEvil
Odd that they would give you code that doesn't work. I'm hardly a .NET expert, but I think you need BeginInvoke to do this sort of stuff.
Arild Fines
Arild Fines
The code in the KB article is wrong, for the reason your error message is giving you. You can't access the properties or methods of controls from threads other than the one they are created on.
--AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.[Project site] [IRC channel] [Blog]
deepdene
deepdene
Forms have a flag called InvokeRequired, this tells you if you need to use the Invoke function to call a delegate to run it from the appropriate thread.

For example ( I use C# since I know how it works compared to VB)

if (form1.InvokeRequired)
form1.Invoke(...)



deepdene
deepdene
To clarify my last post.

InvokeRequired tells you if a invoke is required because the thread is different to the one the form is created in.

Invoke will call a delegate on the same thread the form is created on. Hence avoiding cross-thread action.
Afr0m@n
Afr0m@n
Here's some code written in C# by a contact of me. I think he's called phb5000 on here, and I haven't thanked him yet, so if he's reading this; Thanks! :)

This code can easily be put into a separate class, and as such it can probably be run through a DLL made in C# as well. Using it in VB2005 in DLL form shouldn't be any problem. I really don't think the guy who wrote this minds me putting it on here, because he wrote it for himself and gave it to me because we had the same problem at the same time. :)

  private delegate void SetPropertyCallback(Control control, string property, object value);        private void SetProperty(Control control, string property, object value)        {            Application.DoEvents();             try            {                if (control.InvokeRequired)                {                    SetPropertyCallback d = new SetPropertyCallback(SetProperty);                    this.Invoke(d, new object[] { control, property, value });                }                else                {                    System.Reflection.PropertyInfo pi = control.GetType().GetProperty(property);                    value = Convert.ChangeType(value, pi.PropertyType);                    pi.SetValue(control, value, null);                }            }            catch            {                return;            }        }         private delegate object CallMethodCallback(Control control, string method, object[] parameters);        private object CallMethod(Control control, string method, params object[] parameters)        {            Application.DoEvents();             try            {                if (control.InvokeRequired)                {                    CallMethodCallback d = new CallMethodCallback(CallMethod);                    this.Invoke(d, new object[] { control, method, parameters });                    return null;                }                else                {                    if (parameters == null) parameters = new object[0];                    Type[] types = new Type[parameters.Length];                    for(int i = 0; i < types.Length; i++)                        types = parameters.GetType();                     System.Reflection.MethodInfo mi = control.GetType().GetMethod(method, types);                    object ret = mi.Invoke(this, parameters);                    if (ret != null)                        ret = Convert.ChangeType(ret, mi.ReturnType);                     return ret;                }            }            catch (Exception ex)            {                return null;            }        }
_______________________Afr0Games

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.