.net - vb net update UI controls from separate thread event -
i have 1 class called sftpconnectormanager.vb responsible managing ftp connections server. have form1.vb class main gui. want update progressbar resides on form1 show progress of file transfer. function responsible initiating connection ftp server started on new thread, allows form1 not frozen, good, challenge me being able update progress bar, not working out me @ all.
what have tried/done:
- using delegate update ui separate thread
- using background worker , using it's progress changed event, thought might on here remembered update ui needs happen during file transfer event, sessionfiletransferprogress, not when raise progress changed event.
- read on 20 pages worth of documentation in regards multi-threading , event handling, still don't understand guess...
what need happen:
- updates progress bar ui control, update while file transfer in progress, , needs not freeze ui, needs running on separate thread (which have achieved far believe)
code using:
- https://winscp.net/eng/docs/library_session
- https://winscp.net/eng/docs/library_session_filetransferprogress
form1.vb
public sub sub1(byval x integer, y integer) statuslabel2.text = "connected" progressbar1.maximum = progressbar1.maximum + x progressbar1.value = progressbar1.value + y end sub private sub button1_click(sender object, e eventargs) handles startbtn.click ' if (backgroundworker1.isbusy) <> true ' backgroundworker1.runworkerasync() ' end if 'call xml reader respective values , store them class property dim oconnect = new sftpconnectormanager dim oxmlread xmlreader = xmlreader.create("d:\dale_documents\projects\programming\vbnet\remote_data_backup\sftp_backup\settings.xml") while (oxmlread.read()) dim etype = oxmlread.nodetype if (etype = xmlnodetype.element) if (oxmlread.name = "hostname") oconnect.hostname = oxmlread.readinnerxml.tostring end if if (oxmlread.name = "username") oconnect.username = oxmlread.readinnerxml.tostring end if if (oxmlread.name = "password") oconnect.password = oxmlread.readinnerxml.tostring end if if (oxmlread.name = "port") oconnect.port = oxmlread.readinnerxml.tostring end if if (oxmlread.name = "protocol") oconnect.protocolselection = oxmlread.readinnerxml.tostring end if if (oxmlread.name = "ftpmode") oconnect.ftpmodeselection = oxmlread.readinnerxml.tostring end if if (oxmlread.name = "sshfingerprint") oconnect.sshkey = oxmlread.readinnerxml.tostring end if if (oxmlread.name = "remotepath") oconnect.remotepath = oxmlread.readinnerxml.tostring end if if (oxmlread.name = "localpath") oconnect.localpath = oxmlread.readinnerxml.tostring end if end if end while dim eprotocoloptions = oconnect.protocolselection dim susername = oconnect.username dim shostname = oconnect.hostname dim spassword = oconnect.password dim ssshkey = oconnect.sshkey dim iport = oconnect.port dim sremotepath = oconnect.remotepath dim slocalpath = oconnect.localpath dim bflag = oconnect.bflag dim asoptions = new string() {eprotocoloptions, shostname, susername, iport, spassword, ssshkey, sremotepath, slocalpath} oconnect.testthread(asoptions)
sftpconnectormanager.vb
function startconnectionthread(asoptions) try dim osessionoptions new sessionoptions osessionoptions .protocol = protocolselection .hostname = hostname .username = username .portnumber = port .password = password .sshhostkeyfingerprint = sshkey end using osession new session addhandler osession.filetransferprogress, addressof sessionfiletransferprogress osession.open(osessionoptions) dim otransferoptions new transferoptions otransferoptions.transfermode = transfermode.binary osession.getfiles(remotepath, localpath, false, otransferoptions) osession.close() bflag = false end using messagebox.show("file transfer compelete") return 0 catch ex exception messagebox.show(ex.tostring()) return 1 end try end function public delegate sub setbarvalues(maximum integer, value integer) private sub sessionfiletransferprogress(byval sender object, byval e filetransferprogresseventargs) dim oform1 = form1 dim msd setbarvalues = addressof oform1.sub1 if oform1.invokerequired msd.invoke(1, 1) else oform1.sub1(1, 1) end if 'oform1.progressupdate() 'if (form1.checkforillegalcrossthreadcalls) ' msgbox("illegal cross-thread operation deteced.") 'end if end sub public sub testthread(asoption()) dim osftpconnectionmanager = new sftpconnectormanager dim thread new thread(addressof osftpconnectionmanager.startconnectionthread) osftpconnectionmanager.protocolselection = asoption(0) osftpconnectionmanager.hostname = asoption(1) osftpconnectionmanager.username = asoption(2) osftpconnectionmanager.port = asoption(3) osftpconnectionmanager.password = asoption(4) osftpconnectionmanager.sshkey = asoption(5) osftpconnectionmanager.remotepath = asoption(6) osftpconnectionmanager.localpath = asoption(7) thread.start() end sub
so may see tried use delegate, did fair bit of reading on , believe need update ui elements separate thread, have misunderstood because can't implement concept in own project. ui changes needs happen during sessionfiletransferprogress event.
please guys , girls @ wits end this, final saving grace , don't think able continue learning program if can't understand , implement these concepts.
here simple example shows concepts. has class has long running (sic) activity wants report progress ui. you'll need form 2 buttons, progressbar, , textbox. hope helps conceptually.
public class form1 private sub button1_click(sender object, e eventargs) handles button1.click progressbar1.value = 0 dim foo new someclass(new action(addressof showprog)) foo.simulateactivity() 'long running button2.select() end sub public sub showprog() if me.invokerequired ' on ui? me.invoke(sub() showprog()) ' no, run on ui else progressbar1.increment(1) ' yes, on ui end if end sub private sub button2_click(sender object, e eventargs) handles button2.click 'test if ui available while long running 'press button 2 while long running confirm ui textbox1.text = progressbar1.value.tostring end sub end class public class someclass private _action action public sub new(progress action) me._action = progress end sub public sub simulateactivity() 'runs on thread dim t task t = task.run(sub() x integer = 1 100 me._action() threading.thread.sleep(50) next end sub) end sub end class
Comments
Post a Comment