Highlighted
Super Contributor.
Super Contributor.
196 views

Thread - passing parameters between threads

It is possible to pass parameters between threads:

I have the program start and I need to populate a grid but I want to do it in the background.
It is necessary to pass the type of product that should be loaded on the grid, type of wheel or tires for example:

method-id NEW.
procedure division.
invoke self :: InitializeComponent
goback.
end method.

method-id Form1_Load final private.
procedure division using by value sender as object and type System.EventArgs.
*> ------------------------------------------------ -----------------------------------
*> today I do this, fill a bindingsource but if you have a lot of registration it takes a while.

declare fPdto as type cadProdutos = new cadProdutos
set bindingSource1 :: DataSource to fPdto :: encheProdutos (Lnk-Produtos)

*> I would like to switch to a thread

*> ------------------------------------------------ -----------------------------------
declare thread1 as type Thread
declare myobject as type ThreadWork = new ThreadWork
declare threadDelegate as type ThreadStart= new ThreadStart(myobject::encheProdutos ??????)
set thread1 to new Thread(threadDelegate)
invoke thread1::Start

*> continue the program

set label15 :: Text to wNumCaixa-cfg
*> SAT directory
set w-DirSAT to w-pastaSAT-cfg
set w-DirEntSAT to w-pastaENT-cfg
set w-DirSaiSAT to w-pastaSAI-cfg
set w-DirArqVSAT to w-pastaVDA-cfg
set w-DirArqCSAT to w-pastaVDA-cfg
set wBoolean to false
set self :: Cursor to type Cursors :: Default
end method.

translated by Google

0 Likes
10 Replies
Highlighted
Super Contributor.
Super Contributor.

Re: Thread - passing parameters between threads

There are two ways to do this:

  1. Use async/await (see here for details). This is the most easy way. The async keyword incorporates creation of a new thread and await puts all the code following it into a callback that's being called in the main thread when the function being called using await returns.

  2. Put the data to load in a local variable and conclude the method that's loading the data with Control.Invoke(). NB: You cannot set control properties from any other thread then the main thread. That's why you need to collect your data in a local variable, call Control.Invoke() and copy the data from the variable to the grid control in the corresponding delegate.
0 Likes
Highlighted
Super Contributor.
Super Contributor.

Re: Thread - passing parameters between threads

Thanks, but in version 4.0 it didn't work. I can't forget to mention the version I'm using the next time I ask.

0 Likes
Highlighted
Super Contributor.
Super Contributor.

Re: Thread - passing parameters between threads

Did you check my second suggestion? That's a plain .NET 1.0 feature. No syntactical sugar required. This should work even with Visual COBOL 4.0.

From your event handler's name I was assuming you're doing a Windows Form project. Is my assumption correct?

0 Likes
Highlighted
Super Contributor.
Super Contributor.

Re: Thread - passing parameters between threads

Yes correct windows form, I can execute the threads but I can't pass parameters between them
0 Likes
Highlighted
Super Contributor.
Super Contributor.

Re: Thread - passing parameters between threads

Can you share your definition of ThreadWork class?

I don't see any properties/fields set on that class in your code. That would be the kind of "parameters" supposed to be used:

declare myobject as type ThreadWork = new ThreadWork
set myobject::myArgs = ...
declare threadDelegate as type ThreadStart = new ThreadStart(myobject::doSomethingUseful)

0 Likes
Highlighted
Super Contributor.
Super Contributor.

Re: Thread - passing parameters between threads

In the example I put, I'm populating a bindingSource1 :: DataSource parameter which is LNK-Products,
If you see here the program calls popular, set bindingSource1 :: DataSource to fPdto :: encheProdutos (Lnk-Produtos)

method-id PublicMethod.

01 Lnk-CodPdto    pic x(002).
01 Lnk-NamePdto pic x(020).
working-storage section.
01 any-key pic x.
procedure division.

move 1 to Lnk-CodPdto
declare thread1 as type Thread
declare myobject as type ThreadWorkPublic = new ThreadWorkPublic
declare threadDelegate as type ThreadStart = new ThreadStart(myobject::DoWork)
set thread1 to new Thread(threadDelegate)
invoke thread1::Start

display Lnk-NamePdto

goback.
end method.

class-id ThreadWorkPublic.
method-id DoWork public.
linkage section.
01 Lnk-CodPdto    pic x(002).
01 Lnk-NamePdto pic x(020).
procedure division using Lnk-CodPdto returning Lnk-NamePdto.
open input pdto

set key_pdto to Lnk-CodPdto

read pdto

close pdto

set Lnk-NamePdto to name-pdto

goback.
end method.
end class.


I believe that this way my doubt becomes more readable to be understood.

I hope I haven't complicated any more, and thank you for your time.

Translated by Google

0 Likes
Highlighted
Super Contributor.
Super Contributor.

Re: Thread - passing parameters between threads

Hi,

I think, the best remedy to your problem may be to provide you with a working example.

So, today I created a minimum Windows Forms project for you, containing only the elements required to perform an asynchronous data load and feed it to a DataGridView control.

Please find the Visual Studio 2019 solution at the bottom of this message.

It's packed in a ZIP file. The name is "ProdutosTest.zip".

I noticed that you're using Google Translator to post here in the forum. From the data item names you provided I assume your native language is Portuguese, so I named all data items, methods and comments in Portuguese in my code for you. (Actually, I used Google Translator to do the job, so some of the Portuguese words may be falsely translated.)

This is my first Windows Forms application written in COBOL. So, I first created a C# version of the project and then manually "transpiled" it to COBOL. You will find both projects, the C# version and the COBOL version, in the Visual Studio 2019 solution I provided for download.

 

What is the program composed of?

  1. I used the default Windows Forms project template. That template comes with a default form (Form1).
  2. I added a DataGridView control and a TrackBar control to the default form:
    ► The DataGridView is supposed to display the asynchronously loaded data.
    ► The TrackBar control I just added to be able to fumble around in the form while the data is asynchronously loaded. It serves no other purpose.
  3. I created a text file containing sample data. Portuguese requires UNICODE encoding, so I used .NET to load the data instead of using a COBOL LINE SEQUENTIAL file data item.

 

What does the program do?

Actually, the program is quite simple. The important part for your problem is implemented into METHOD-ID EnchimentoProdutos and METHOD-ID ProdutosRecebidos:

EnchimentoProdutos
Is executed on a separate worker thread. It adds new data from the string array to the binding source.

ProdutosRecebidos
Is "called" by EnchimentoProdutos to update the DataGridView control after the binding source has been updated by the worker thread. ProdutosRecebidos is run on the main thread.

 

What are the event handlers for?

  1. When the form is initialized, I load the text data into a string array and initialize a delegate for ProdutosRecebidos. The delegate stores which method to call on the main thread when the worker thread wants to update the form. Next, I initialize the binding source with a 1-column DataTable object.
  2. When the form has loaded, I start the worker thread, providing it with the function to be run by the worker thread in ThreadStart (EnchimentoProdutos).
  3. When the fom is about to close, I signal to the worker thread to stop providing any more data to the form (because it will go away) and to gracefully shut-down.

 

A picture is worth a thousand words.

So, here's a quick visual screencast depicting the Visual Studio 2019 solution I created for your:

Windows Forms Thread Test Project.gif

 

HTH,
Axel

Highlighted
Super Contributor.
Super Contributor.

Re: Thread - passing parameters between threads

As you can see from my code, I passed parameters to the other thread using the WORKING-STORAGE SECTION. So, in my sample the data is "globally" available within the Form1 object to both threads.

Alternatively, you may also pass parameters to the worker thread using a single argument, i.e. a dedicated class object. Yet, that option would have bloated the sample project, so I refrained from that option here.

0 Likes
Highlighted
Super Contributor.
Super Contributor.

Re: Thread - passing parameters between threads

Thank you very much for your help!
I will study your code to use in my application.
A doubt is that thread within the same class / form works and if that thread is in another class / form.

But it's very helpful, you don't have to worry about putting it in Portuguese.
0 Likes
Highlighted
Super Contributor.
Super Contributor.

Re: Thread - passing parameters between threads

You are very welcome.

 

You wrote that you are in doubt about data passing threads from the same class or other classes.

Actually, all data in your program is always shared across all threads of a process. It doesn't make a difference what class the data belongs to. A class is just an organizational unit for programmers, not for the machine executing the code.

 

There's one exception to this rule: data from ThreadLocal<T> or static data tagged with the ThreadStaticAttribute class can only be accessed from the thread that created the particular object.

 

If you believe there is a risk of more than one thread accessing the same data at the same time, you might want to restrict access to such data, so that only one single thread may access that data while all other threads trying to access that data are blocked until the first thread finishes accessing that data. Visual Cobol provides the SYNC statement for handling such requirement:

$set ilusing(System)

class-id Mutual.Test.
  01 myLock object private value new Object().
  01 myCriticalData binary-long private value 0.

  method-id DoSomething private.
    sync myLock
      set myCriticalData to myCriticalData + 1
    end-sync
  end method.
end class.

 

0 Likes
The opinions expressed above are the personal opinions of the authors, not of Micro Focus. By using this site, you accept the Terms of Use and Rules of Participation. Certain versions of content ("Material") accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company. As of September 1, 2017, the Material is now offered by Micro Focus, a separately owned and operated company. Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.