3

I am dynamically generating some labels with the help of data from the database. Then I added some events to these dynamically generated labels. I am trying to run the click events of labels in a new thread. But I couldn't figure it out so far. Any leads will be really helpful.

private void LoadData(string DeviceCode)
{
    //here i am generating the labels (not shown)
    //adding the event handler
    lb_DeviceData[i].Click += new EventHandler(CalculateClick);
    lb_DeviceData[i]..Tag = i;
}

private void CalculateClick(object sender, EventArgs e)
{
    Label MyLabel = (Label)sender;
    Thread t = new Thread(ThreadedMethodForCalc);    //can i pass MyLabel into this method?
    t.Start();
}

private void ThreadedMethodForCalc()
{
   //complex calculation here
   // is it possible to pass 'MyLabel' in this method
}          

Pavel Anikhouski
  • 21,776
  • 12
  • 51
  • 66
master_yoda
  • 463
  • 3
  • 11
  • Is your problem passing the MyLabel value into another function, or is your problem that you don't know how to dynamically create the click events for these labels? – emmademontford Nov 18 '19 at 12:47
  • What does this code do that you don't want it to? Or not do that you do want it to? – rory.ap Nov 18 '19 at 12:47
  • I need to use 'MyLabel' inside ThreadedMethodForCalc. How to pass labels to ThreadedMethodForCalc? and is it the right way of doing threading? – master_yoda Nov 18 '19 at 12:49
  • You can make `ThreadedMethodForCalc()` have a parameter of `MyLabel` so you can use this within the function - see @Fabjan's answer. – emmademontford Nov 18 '19 at 12:51
  • 2
    You can pass controls to what you want, you can also save it to static variables, and every thread can access it. No problem. But it can get difficult to communicate with this control, cause you can call only methods of that control, from within the thread, the control was created in. This can be handled, but it's an extra effort. (Check on InvokeRequired Property of Control) – Holger Nov 18 '19 at 12:51
  • 1
    I think using async/await would be a viable alternative. What do you need to do with `MyLabel`? Set Text? Then you may want to use IProgress with async/await Task ... – Fildor Nov 18 '19 at 12:55
  • @Fildor OP probably needs to get a little more accustomed to multithreading before wrapping the mind around async/await. – rory.ap Nov 18 '19 at 12:57
  • 'MyLabel' contains the device ID. I need this ID to identify the calculation methods and formulas. – master_yoda Nov 18 '19 at 12:58
  • 1
    @rory.ap I don't know OP's skill level. It is an alternative which I personally find to be a million times more readable and straight-forward than using a thread in this scenario. But it's not an answer to the question, anyway. Just wanted to point out, that there _is_ another route that _could_ be followed. – Fildor Nov 18 '19 at 12:59
  • @sunny_old_days Then why don't you just pass the id instead if the whole Label object? – Fildor Nov 18 '19 at 13:00
  • The IDs are getting from Database. I am assigning it to labels (dynamic labels!) – master_yoda Nov 18 '19 at 13:04

2 Answers2

3

Well, the simplest way is to change the signature of the method and use closure:

Thread t = new Thread(() => ThreadedMethodForCalc(MyLabel));
t.Start();

...

private void ThreadedMethodForCalc(Label myLabel)
{
}

Btw to update the UI in another thread you can use Control.Invoke(...).

For more information check this article from MSDN.

Fabjan
  • 13,506
  • 4
  • 25
  • 52
  • 1
    @PavelAnikhouski True but only `object` is allowed and then you'd have to cast it back to its original type – Fabjan Nov 18 '19 at 12:55
  • This worked. All my form controls are in the main thread. During this calculation thread, i wanna alter some display in the main thread. I tried inside ThreadedMethodForCalc and got an error like below! System.InvalidOperationException: 'Cross-thread operation not valid: Control 'MainPanel' accessed from a thread other than the thread it was created on.' – master_yoda Nov 18 '19 at 13:02
  • @sunny_old_days Check `.Invoke` function and the article that I've posted in my answer – Fabjan Nov 18 '19 at 13:20
1

Yo can your method accepting label

private void ThreadedMethodForCalc(object label)
{
    Label MyLabel = (Label)label;
    //complex calculation here
    // is it possible to pass 'MyLabel' in this method
} 

And then use in thread Start

t.Start(sender);

But you aren't allowed to modify the control properties outside the UI thread

Pavel Anikhouski
  • 21,776
  • 12
  • 51
  • 66