1

I'm not familiar with Multi-threading programming , i only know a few about the basics. i want to set a value for example a label text from another thread to main thread(i even don't know that i'm right about main thread but you'll what i want to do when you saw the code) I need a solution to work for others controls and controls's values too(like location of a button)

static int s = 0;
        void v()
        {
            for (int i = 0; i > -1; i++)
              { 
                s++;
                label1.Text = s.ToString();
              }

        }   
private void buttonX1_Click(object sender, EventArgs e){

            ThreadStart ts = new ThreadStart(v);
            Thread trd = new Thread(ts);
            trd.Start();
}

thats my whole code and i have only one label and one button when i click on button i get this error:

Cross-thread operation not valid: Control 'label1' accessed from a thread other than the thread it was created on.

any help will be appreciated.

Sam
  • 43
  • 9
  • Have you tried to update the label on the UI thread with Application.Current.Dispatcher.Invoke(() => { label1.Text = "updated from non UI thread"; });? – IamK Sep 01 '19 at 11:59
  • @C1sc0 Is that for winforms? – mjwills Sep 01 '19 at 12:23
  • @Sam Have you Googled for `invoke method in UI thread winforms`? – mjwills Sep 01 '19 at 12:24
  • @mjwills i assumed he/she works with WPF, for winforms it is a little different (you have to create a delegate and check with InvokeRequired property that the current thread id differs from the UI thread id and if so, Invoke the delegate method) – IamK Sep 01 '19 at 12:55
  • 1
    Possible duplicate of [How do I update the GUI from another thread?](https://stackoverflow.com/questions/661561/how-do-i-update-the-gui-from-another-thread) – Joelius Sep 01 '19 at 14:22
  • Please tell us what you want the code to **do**. – mjwills Sep 01 '19 at 23:51
  • @mjwills i even didnt know anything about invoke method but the solution that Faeze posted was very useful and thanks all of you for trying to help me. – Sam Sep 02 '19 at 13:09
  • You probably want to declare `s` as `volatile` too. And you have a race condition with `s`. You really should do some sort of `lock`ing. – Enigmativity Sep 02 '19 at 23:43
  • @Enigmativity i used this ```this.Invoke((MethodInvoker)delegate { label1.Text = s.ToString(); })``` and it worked but i just noticed when i use ```if``` for checking ```s``` i cant use my ```form``` or ```button``` anymore its like they trap in some infinite loop or something like that .[if(s == 1000)s=0;].why its happening ?they are in another thread ! – Sam Sep 03 '19 at 11:32
  • @Sam - You're probably flooding the message pump. There are better ways to do this. I'm about to get on a plane for the next 24 hours so I cant help right now, sorry. – Enigmativity Sep 03 '19 at 11:53

2 Answers2

4

If your V method return string, you can try this :

private async void buttonX1_Click (object sender, EventArgs e) {

    string str = await Task.Factory.StartNew(()=> v());

    label1.Text = str;
}
Majid Kiani
  • 136
  • 3
  • Async and await keywords are used for multi-tasking and also multi-threading programming :)) – Majid Kiani Sep 03 '19 at 04:37
  • I've never heard the term "Multi-Tasking" in this context but I think I know what you mean, yes that exists. But it's NOT parallel and it's also not multithreading. I advise you to read [this msdn blog](https://blogs.msdn.microsoft.com/benwilli/2015/09/10/tasks-are-still-not-threads-and-async-is-not-parallel/), [this cleary blog](https://blog.stephencleary.com/2013/11/there-is-no-thread.html) and [this SO answer](https://stackoverflow.com/a/34681101/10883465). – Joelius Sep 03 '19 at 04:54
2

use Invoke for cross threading

this.Invoke((MethodInvoker)delegate { label1.Text = s.ToString(); });

in short form delegate in C# is similar to the function pointer in C/C++. for more information take a look at this link

Faeze
  • 118
  • 1
  • 7
  • thanks , it worked . if you have time can you please explain shortly what is ```delegate``` or ```MethodInvoker``` and how it's work ?just curious . – Sam Sep 02 '19 at 12:50
  • i just noticed when i use ```if``` for checking ```s``` i cant use my ```form``` or ```button``` its like they trap in infinite loop or something like that .[```if(s == 1000)s=0;```].why its happening ?they are in another thread ! – Sam Sep 02 '19 at 13:34
  • 1
    @Sam , in short form `delegate` in C# is similar to the function pointer in C/C++. for more information take a look at this link: [link](https://www.geeksforgeeks.org/c-sharp-delegates/). Dear @Sam if the answer worked for you, vote it up. – Faeze Sep 03 '19 at 13:04
  • yes it work an i voted, can you please help me with ```if``` problem that i told you about it on higher comment ? – Sam Sep 03 '19 at 21:43
  • 1
    @Sam, I checked your if condition and it worked. the problem is that the condition `if(s==100) s=0` occurred too fast that you might not have noticed it. if you put a breakpoint on the line s=0, you'll see program stops there. – Faeze Sep 04 '19 at 05:56
  • is there any way to avoid Form and it's other controls(in this case button) getting freeze ? i build a very simple and small game(Snake) two years ago and i used ```timer``` for moving and checking movements events like eating or hitting and when snake grows like 100 ```button```s the ```timer```s that i used goes slow because of 100 or more checking methods for all button and that was the reason i start thinking to use multi-threads instead of ```timer```s and with that ```MethodInvoker``` of your solution i'm very close to finish my snake game and fix my other games's timing problems. – Sam Sep 06 '19 at 22:38
  • that's was the comment limit i couldn't add last thing,thanks a lot Compatriot. – Sam Sep 06 '19 at 22:41