Results 1 to 10 of 10

Thread: Backgroundworker query

  1. #1

    Thread Starter
    New Member
    Join Date
    Oct 2021
    Posts
    12

    Backgroundworker query

    I have an application which has a primary thread with 3 forms open.

    I have a fourth form which runs a backgroundworker which is taking data from a telnet session where data is randomly arriving. This form contains a datagridview and I have created a delegate which analyses the incoming data & adds to the datagridview.

    All the above are working fine.

    One of the other 3 forms contains a datagridview which I need to scan its contents (which are static) & potentially update a cells background colour. I need to call this from within the backgroundworker. The form has a public sub which I am trying to call and pass 2 strings from within the backgroundworker. This is the part I cannot get to work.

    Any help appreciated (I am still getting my head around this delegate stuff).

    Thanks
    Clive

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Backgroundworker query

    Quote Originally Posted by g4naq View Post
    I need to call this from within the backgroundworker.
    You are never "within the backgroundworker". Presumably, you mean from within the BackgroundWorker's DoWork eevnt handler, which is part of the form, not the BackgroundWorker.

    Assuming that's true, that code will be executing on a secondary thread so, if you want to interact with a control, you're going to need to marshal a call to the UI thread at some point. You have two choices:

    1. You can call a method of the other form from within the DoWork event handler and then the other form can marshal to the UI thread.
    2. You can marshal to the UI thread first, then call a method of the other form from there.

    Based on the little information you've provided, I'd probably suggest the second option, so you keep all the multi-threading stuff in the one form.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  3. #3
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Backgroundworker query

    If you're using a BackgroundWorker then you shouldn't really be invoking delegates. The whole reason the BackgroundWorker exists is to avoid that. It's not wrong per se but, if you're going to do it, you may as well not use a BackgroundWorker in the first place. The idea is that you call methods and handle events, which even the biggest newbie has done before. You call RunWorkerAsync and handle DoWork. If you want to interact with the UI during the background work, you call ReportProgress and handle ProgressChanged. If you want to interact with the UI after the background work, you handle RunWorkerCompleted. That's really all there is to it. You can pass data from RunWorkerAsync to DoWork, from DoWork through ReportProgress to ProgressChanged and from DoWork to RunWorkerCompleted.

    In your case, what you probably ought to be doing is calling ReportProgress and passing the required data, then handling ProgressChanged and interacting with the other form from there. What that interaction should be actually depends on the relationship between the forms. It may be that you should be calling a method of the other form directly, or it might be that you should be raising an event for the other form to handle. It depends which one opened the other.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  4. #4

    Thread Starter
    New Member
    Join Date
    Oct 2021
    Posts
    12

    Re: Backgroundworker query

    Thanks for your response. I used a backgroundworker as I had no success using other approaches to dealing with the incoming telnet data without causing what I suspect is some form of blocking.

    If you can suggest a better way of dealing with the telnet session data I will rewrite it as I would prefer another approach. Meanwhile I will look at how to use your suggestions.

  5. #5
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,102

    Re: Backgroundworker query

    I would say that other approaches would only make sense if the telnet data has nothing to do with a form. That's probably not a good description. If you can picture the program as being two parts, one being all the forms and everything the user interacts with, while the other part is the telnet part, then if the telnet part can keep running steadily while all the forms are doing whatever they are doing, then there might be a better approach. If the telnet part is launched by some action in a form, and is only running while that form is meaningful, then the backgroundworker approach is probably best.

    Either way is possible. What is best comes down to whether the telnet part makes sense as a part of form X, or makes more sense as being separate from all the forms. If it only makes sense as part of form X, then ReportProgress is the way I'd be going about it. That does kind of require that there be a loop, however vague, because you'd be wanting to report progress periodically, but telnet could well have something like a loop. If you get all your data in one giant whack, then there would be no point at which to report progress, which would be a problem. The background would complete before ever having an opportunity to alert the foreground to update itself. With telnet, you are likely doing something more like: Get data, report progress, get more data, report progress, etc. That would work well as either a background worker or as a stand alone thread, and the only difference between the two is whether they make sense as part of a form or not.
    My usual boring signature: Nothing

  6. #6
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Backgroundworker query

    Further to what Shaggy said, if it makes sense that the telnet code not be part of a form, you could define a class that did all the telnet work and raised events at appropriate times. One or multiple forms could then create instances of that class and handle those events. You could have the events raised on the UI thread, in which case you'd want to use the SynchronizationContext class to manage that, or you could have the events raised on a secondary thread and the form could be responsible for marshalling back to the UI thread. .NET has a number of classes that raise events on secondary threads and some that give you the option of either. Those that allow either usually have a SynchronizingObject property that you can assign a form or control to and then they will call Invoke or BeginInvoke on that internally to do the marshalling. Examples include the FileSystemWatcher class and the System.Timers.Timer class.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  7. #7

    Thread Starter
    New Member
    Join Date
    Oct 2021
    Posts
    12

    Re: Backgroundworker query

    Thanks for the suggestions.. my knowledge on some of the options you mention is near zero at present...

    The software is for Ham Radio and the main form is a logbook (datagridview), a 2nd form for adding entries manually to the logbook and a 3rd form provides a read-only matrix/map..

    The Telnet form (another datagridview) & associated backgroundworker is invoked from the menu bar of the main form and taking a feed of radio stations heard... Data is arriving with quite regularly and needs to be split/dealt with as typically equates to adding multiple rows to the grid.

    I need several interactions from the Telnet data.
    1) add rows to the datagridview working which I have used the delegate to do a row.insert (appears to work correctly)
    2) double click a row to populate the manual entry form (works fine).
    3) when data is received from the Telnet session check whether I need to update the 3rd form/matrix to highlight a square (change background colour) based on the data.. This is where I am asking for help.
    4) Update another form (which I have yet to create) which provides a subset (sorted) list of the data in the Telnet datagridview

    I have not used progress changed until now. I created a class to use with progress changed & added the row to the datagridview here. This has meant I have removed the delagate. I hope this approach is better?

    Clive
    Last edited by g4naq; Jan 19th, 2024 at 11:39 AM.

  8. #8
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,102

    Re: Backgroundworker query

    Quote Originally Posted by g4naq View Post
    Thanks for the suggestions.. my knowledge on some of the options you mention is near zero at present...
    We all start there.


    The software is for Ham Radio and the main form is a logbook (datagridview), a 2nd form for adding entries manually to the logbook and a 3rd form provides a read-only matrix/map..

    The Telnet form (another datagridview) & associated backgroundworker is invoked from the menu bar of the main form and taking a feed of radio stations heard... Data is arriving with quite regularly and needs to be split/dealt with as typically equates to adding multiple rows to the grid.

    I need several interactions from the Telnet data.
    1) add rows to the datagridview working which I have used the delegate to do a row.insert (appears to work correctly)
    2) double click a row to populate the manual entry form (works fine).
    3) when data is received from the Telnet session check whether I need to update the 3rd form/matrix to highlight a square (change background colour) based on the data.. This is where I am asking for help.
    4) Update another form (which I have yet to create) which provides a subset (sorted) list of the data in the Telnet datagridview

    I have not used progress changed until now. I created a class to use with progress changed & added the row to the datagridview here. This has meant I have removed the delagate. I hope this approach is better?

    Clive
    That's quite a good project.

    What I would suggest would be that you think a bit more about the telnet and the DGV that you are filling from that. Specifically, I would suggest that you separate out the receiving and processing of the telnet data from EVERYTHING else. One thread (and I would tend to use a Thread for this) would be getting the telnet data and putting it into something, but not into a control, or something that can be displayed. If there are multiple columns, I'd be putting the data into a datatable. That's all I'd be having the thread doing...well, that and raising some events.

    As to the events, I'd want to raise them on the UI thread periodically. Figuring out when is something that you'd have a better feel for. Are there pauses in the telnet data that would make reasonable times to update the UI? To be reasonable, the pauses would have to be identifiable. If there aren't good pauses, then perhaps there could be a timer, as JMC suggested, that raised a tick event on its own thread, periodically. The updates to the UI could happen on the timer ticks. This would mean that the UI would only be updated every so often, but you could make the timer interval fast enough that the result would be acceptable to the user.

    One thing I would be inclined to do for the UI would be to clone the datatable. Basically, I'd have one that the telnet thread would be updating as data arrived, and perhaps that would be cloned periodically such that the UI thread could work with the clone. I'm not sure this would work, but it would mean that the UI wouldn't need to worry about the datatable changing while it was doing work, especially if the datatable was only cloned once every couple seconds. Even once a second would likely be fine. That design would mean that the visible data would tend to be stale, though only by a second or two, which might be acceptable.

    That may not be the best approach, either. Getting the data into the datatable is a clear task for the telnet thread. What you then do with the datatable...well, there are lots of options there.
    My usual boring signature: Nothing

  9. #9
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,687

    Re: Backgroundworker query

    Quote Originally Posted by Shaggy Hiker View Post
    One thing I would be inclined to do for the UI would be to clone the datatable. Basically, I'd have one that the telnet thread would be updating as data arrived, and perhaps that would be cloned periodically such that the UI thread could work with the clone. I'm not sure this would work, but it would mean that the UI wouldn't need to worry about the datatable changing while it was doing work, especially if the datatable was only cloned once every couple seconds. Even once a second would likely be fine. That design would mean that the visible data would tend to be stale, though only by a second or two, which might be acceptable.
    I don't think you'd need to clone it. The DataTable could be bound to a DataBindingSource, which would then be bound to the grid. You can then add to the datatable and have it just showup ... if you need to do any processing on the grid, use a timer that ticks off every so often and updates the grid as needed.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  10. #10
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: Backgroundworker query

    It would be interesting to see the 'telnet' code. Also post a link to the protocol of the data coming from the device.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width