[c#] Frage zu Thread's / Threading

07/15/2013 11:54 .Stefan#16
Quote:
Originally Posted by tolio View Post
wenn du das genau so aufrufst dann friert natürlich deine hauptform(/der thread dieser) ein und nicht der thread den du neu gestartet hast, wenn du den einfrieren willst musst es halt im kontext des neu erstellten threads aufrufen
Sorry, ich kann dir momentan nicht ganz folgen. Aber ich denke, dass ich das grundsätzlich verstanden habe, was du meinst. Wie kann ich denn das so einstellen, dass genau der Thread gestopt wird ( Thread.Sleep(2000) ) und nicht die Hauptform. Eigentlich steht. Thread.sleep ja in der Methode des Thread's :/
07/15/2013 12:34 Kraizy​#17
Zeig uns mal den gesamten Code, wo du den Thread startest etc.
07/15/2013 13:15 .Stefan#18
Quote:
Originally Posted by Kraizy​ View Post
Zeig uns mal den gesamten Code, wo du den Thread startest etc.
Okay.

Funktioniert :
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Threading.Tasks;

namespace ui_threading
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Task t1 = new Task(Task1);

            t1.RunSynchronously();
        }

        private void Task1() 
        {
            label1.Text = "12";
        }

    }
}
Form wird erst nach den 5 Sekunden angezeigt.

Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Threading.Tasks;

namespace ui_threading
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Task t1 = new Task(Task1);

            t1.RunSynchronously();
        }

        private void Task1() 
        {
            label1.Text = "12";
            Thread.Sleep(5000);
            label1.Text = "1234";
        }

    }
}
07/15/2013 13:25 Kraizy​#19
Hab die Task Klasse zwar noch nicht benutzt, aber allein der Name RunSynchronously sagt doch schon alles.
07/15/2013 14:46 .Stefan#20
Quote:
Originally Posted by Kraizy​ View Post
Hab die Task Klasse zwar noch nicht benutzt, aber allein der Name RunSynchronously sagt doch schon alles.
Okay, ich habe den Code nun geändert zu :

Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;

namespace ui_threading
{

    public partial class Form1 : Form
    {

        private delegate void UpdateStatusDelegate(string status);

        public void UpdateStatus(string status)
        {
            if (InvokeRequired)
                BeginInvoke(new UpdateStatusDelegate(InnerUpdateStatus), new object[] { status });
            else
                InnerUpdateStatus(status);
        }

        private void InnerUpdateStatus(string status)
        {
            label1.Text = status;
        }

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Task t1 = new Task(Task1);

            t1.Start();
        }

        private void Task1() 
        {
            UpdateStatus("Text1");
            Thread.Sleep(5000);
            UpdateStatus("Text2");
        }

    }
}
Damit funktioniert alles soweit. Jedoch scheint mir das mit den 2 Methoden für das Label etwas aufwendig. Aber möglich. Kennt jemand bessere Methoden ?
07/15/2013 15:06 qkuh#21
Du kannst es auch so machen:
Code:
private void setEnabled(string control, bool setEnabled)
        {
            Button btn = (Button)Controls.Find(control, true)[0];

            if (btn.InvokeRequired)
            {
                btn.Invoke((MethodInvoker)delegate
                {
                    btn.Enabled = setEnabled;
                });
            }
            else
            {
                btn.Enabled = setEnabled;  
            }
        }
07/15/2013 15:43 Shawak#22
Quote:
Originally Posted by .Stefan View Post
Okay, ich habe den Code nun geändert zu :

Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;

namespace ui_threading
{

    public partial class Form1 : Form
    {

        private delegate void UpdateStatusDelegate(string status);

        public void UpdateStatus(string status)
        {
            if (InvokeRequired)
                BeginInvoke(new UpdateStatusDelegate(InnerUpdateStatus), new object[] { status });
            else
                InnerUpdateStatus(status);
        }

        private void InnerUpdateStatus(string status)
        {
            label1.Text = status;
        }

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Task t1 = new Task(Task1);

            t1.Start();
        }

        private void Task1() 
        {
            UpdateStatus("Text1");
            Thread.Sleep(5000);
            UpdateStatus("Text2");
        }

    }
}
Damit funktioniert alles soweit. Jedoch scheint mir das mit den 2 Methoden für das Label etwas aufwendig. Aber möglich. Kennt jemand bessere Methoden ?
geht viel einfacher:

Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;

namespace ui_threading
{

    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            System.Threading.Tasks.Task.Factory.StartNew(() =>
            {
                Label1.Text = "Text1";
                Thread.Sleep(5000);
                Label1.Text = "Text2";
            });
        }
    }
}
07/15/2013 16:34 Schlüsselbein#23
[Only registered and activated users can see links. Click Here To Register...]
07/15/2013 19:44 .Stefan#24
Quote:
Originally Posted by qkuh View Post
Du kannst es auch so machen:
Code:
private void setEnabled(string control, bool setEnabled)
        {
            Button btn = (Button)Controls.Find(control, true)[0];

            if (btn.InvokeRequired)
            {
                btn.Invoke((MethodInvoker)delegate
                {
                    btn.Enabled = setEnabled;
                });
            }
            else
            {
                btn.Enabled = setEnabled;  
            }
        }
Sieht auch nicht gerade einfacher aus ^^
Quote:
Originally Posted by Shawak View Post
geht viel einfacher:

Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;

namespace ui_threading
{

    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            System.Threading.Tasks.Task.Factory.StartNew(() =>
            {
                Label1.Text = "Text1";
                Thread.Sleep(5000);
                Label1.Text = "Text2";
            });
        }
    }
}
Bist du dir sicher, dass dies so funktioniert. Bei mir kommt immer noch der Fehler : Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement lbl_test erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde.

Quote:
Originally Posted by Schlüsselbein View Post
[Only registered and activated users can see links. Click Here To Register...]
Okay muss ich mir näher ansehen.

Danke für die Antworten.

Ich hätte eine weitere kleine Frage : Wie kann ich eine 2. Klasse erstellen, die Methoden beinhaltet, die auch z.B Label's ändern kann ?
07/15/2013 22:28 Shawak#25
Kombinier einfach das was ich geschrieben habe mit dem von Schlüsselbein.
07/15/2013 22:33 .Stefan#26
Quote:
Originally Posted by Shawak View Post
Kombinier einfach das was ich geschrieben habe mit dem von Schlüsselbein.
Okay das funktioniert wunderbar :)

Jedoch eine weitere kleine Frage :

Wie kann ich eine 2. Klasse erstellen, die Methoden beinhaltet, die auch z.B Label's ändern kann ?
07/16/2013 01:56 tolio#27
übergib referenzen zu den objekten an die neuen klassen
07/16/2013 07:46 .Stefan#28
Quote:
Originally Posted by tolio View Post
übergib referenzen zu den objekten an die neuen klassen
Könntest du mir ein kleines Beispiel geben :s ?
07/17/2013 09:00 'Aleo#29
Quote:
Originally Posted by .Stefan View Post
Könntest du mir ein kleines Beispiel geben :s ?
Code:
void ChangeText(Label Control, string text)
        {
            Control.Text = text;
        }
Wäre eine Möglichkeit in C#.
07/17/2013 09:41 Shawak#30
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;

namespace ui_threading
{

    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            System.Threading.Tasks.Task.Factory.StartNew(() =>
            {
                 this.Invoke(() =>
                 {
                        Label1.Text = "Text1";
                        Thread.Sleep(5000);
                        Label1.Text = "Text2";
                 });
            });
        }
    }
}
Sollte funktionieren

Ansonsten;
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;

namespace ui_threading
{

    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            System.Threading.Tasks.Task.Factory.StartNew(() =>
            {
                 this.Invoke(() {  Label1.Text = "Text1"; });
                 Thread.Sleep(5000);
                 this.Invoke(() {  Label1.Text = "Text2"; });
            });
        }
    }
}
Lg