vb.net - Thread safety problems trying to databind across threads -


i have form datagrids bound bindinglist of data being populated constant stream of data tcpip connection. tcpip connection on thread should constatly loop , when finds enough data create instance of class data , add bindinglist(of data). getting error says "cross-thread operation not valid: control '' accessed thread other thread created on.". stack trace points line adds new data bindinglist(of data)

datalist.insert(0, dataitem) 

what strange me keeps going on , populates datagrid properly. not experienced multithreaded programming , of code has been asynchronous. have datalock , mutexes(something learned not sure using correctly). read somewhere using events if newdata event isn't necessary can rid of it. in making code thread safe appreciated.

the binding on form this:

mydatagrid.datasource = mydatareader.datalist 

here class launching tread , reading data(sorry know it's lot of code didn't want leave out important):

public class datareader     implements inotifypropertychanged #region "properties" dim datamutex mutex dim unparsedmutex mutex dim mip_address string dim convertingdata boolean = false public property ip_address() string             return mip_address     end     set(byval value string)         mip_address = value     end set end property dim mport integer public property port integer             return mport     end     set(byval value integer)         mport = value     end set end property private withevents mdatalist bindinglist(of data) public readonly property datalist bindinglist(of data)             return mdatalist     end end property public event valuechanged eventhandler private event newdataavaiable(byval newdata bindinglist(of data)) private munparseddata string = "" private property unparseddata string             return munparseddata     end     set(byval value string)         munparseddata = value     end set end property #end region #region "private variables" dim mtcpipclient tcpclient dim mconnected boolean dim mtcpipstream networkstream dim mlasterror string dim mdatathread system.threading.thread private datalock new object #end region #region "constructors" public sub new(byval ipaddress string, byval port integer)     datamutex = new mutex(false, "mutexdata")     unparsedmutex = new mutex(false, "mutexunparseddata")     mip_address = ipaddress     mport = port     mconnected = false     mdatalist = new bindinglist(of data)     datalist.raiselistchangedevents = true end sub #end region #region "events" public event propertychanged propertychangedeventhandler implements inotifypropertychanged.propertychanged protected sub onpropertychanged(byval name string)     raiseevent propertychanged(me, new propertychangedeventargs(name)) end sub #end region #region "methods" public sub connecttcpip()     try         if not mtcpipclient nothing andalso mtcpipclient.connected             mlasterror = "connection error:already connected"             exit sub         elseif string.isnullorempty(mip_address)             mlasterror = "connection error:no ip address"             exit sub         end if         datalist.clear()         unparseddata = string.empty          mtcpipclient = new tcpclient()         mtcpipclient.connect(mip_address, mport)         if mtcpipclient.connected             mtcpipclient.receivetimeout = 500             mtcpipclient.sendtimeout = 500             mtcpipclient.lingerstate = new system.net.sockets.lingeroption(false, 0)             mtcpipclient.receivebuffersize = 100000             mtcpipclient.sendbuffersize = 100000             mtcpipstream = mtcpipclient.getstream             launchdatathread()             if mdatathread.isalive mconnected = true         else             mlasterror = "connection error:unknown reason"             exit sub         end if     catch ex exception         messagebox.show(ex.message & ex.stacktrace)     end try end sub public sub disconnect()     disconnecttcpip()     killdatathread() end sub private sub disconnecttcpip()     if not mtcpipclient nothing andalso mtcpipclient.connected         mtcpipclient.close()         mtcpipclient = nothing     end if end sub public function isconnected() boolean     if mtcpipclient nothing orelse mdatathread nothing return false     return mtcpipclient.connected andalso mdatathread.isalive end function public sub launchdatathread()     mdatathread = new system.threading.thread(addressof readdata)     mdatathread.start() end sub public sub killdatathread()     if not mdatathread nothing andalso mdatathread.isalive()         mdatathread.abort()     end if     mdatathread = nothing end sub public sub readdata()     try         while true             dim count short = 0             while not mtcpipclient.connected andalso count <= 5                 system.threading.thread.sleep(5000)                 connecttcpip()                 count += 1             end while              if mtcpipclient.connected = false exit sub             dim databuffer(500) byte             dim readbytes integer = 0             unparsedmutex.waitone()             while mtcpipstream.dataavailable                 readbytes = mtcpipstream.read(databuffer, 0, 500)                 unparseddata += system.text.encoding.ascii.getstring(databuffer.take(readbytes).toarray())             loop             unparsedmutex.releasemutex()             if unparseddata.length > 0 processnewdata()             system.threading.thread.sleep(500)         end while      catch ex exception         windows.forms.messagebox.show(ex.message + environment.newline + ex.stacktrace)     end try end sub public sub processnewdata()     dim datatoprocess string = ""     unparsedmutex.waitone()     if string.isnullorempty(unparseddata)         unparsedmutex.releasemutex()         exit sub     end if     datatoprocess = unparseddata.substring(0, unparseddata.lastindexof("plc") + 3)     unparseddata = unparseddata.remove(0, datatoprocess.length)     unparsedmutex.releasemutex()     if not string.isnullorempty(datatoprocess)         dim matches = datatoprocess.split(";"c)          if matches.count > 0             dim newdata new bindinglist(of data)             try                 = 0 matches.count - 1                     newdata.insert(0, new data(matches(i).value))                 next                 raiseevent newdataavaiable(newdata)             catch ex exception                 windows.forms.messagebox.show(ex.message + environment.newline + ex.stacktrace)             end try         end if     end if end sub private sub onnewdata(byval newdata bindinglist(of data)) handles me.newdataavaiable     synclock datalock         datamutex.waitone()         each dataitem data in newdata             datalist.insert(0, dataitem)             if datalist.count > 5000 datalist.removeat(5000)         next         datamutex.releasemutex()     end synclock end sub #end region end class 

update: bindinglist(of data) never need updated ui thread changing data should mdatathread in datareader class.

look invokerequired, invoke, delegate.

example here, have udp server in background thread(background worker) receiving messageentries , listview1 in main thread. legacy winforms project on net4.0

the following called background thread:

delegate sub setlistviewcallback(byval newmsg messageentry)  private sub additemtolistview(byval newmsg messageentry)     dim item1 new listviewitem(newmsg.time.tostring(), 0)     item1.subitems.add(newmsg.ip.tostring())     if listview1.invokerequired         dim d new setlistviewcallback(addressof additemtolistview)         me.invoke(d, new object() {newmsg})     else         listview1.items.add(item1)     end if end sub 

edit: checked method bindedlist datasource datagridview , still works. difference conditional if checks if datagridview object requires invoke , in else section put modification of bindedlist.


Comments

Popular posts from this blog

android - Get AccessToken using signpost OAuth without opening a browser (Two legged Oauth) -

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: mockito -

google shop client API returns 400 bad request error while adding an item -