Diskuze: Cross-thread operation not valid
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.


Dispose() se volá automaticky, když je objekt mazán Garbage Collectorem (nebo na konci konstrukce using).
Pokud tuto třídu používáš někde v using, tak zkus poslat ten kousek kódu i s tím. A používáš tam více vláken?
drbohlav.lukas:8.4.2013 15:28
Mám to vlastně automaticky generovaný podle mě, ale nemůžu se dostat k tomu, kdy tam ta chyba vzniká, abych to mohl nějak odstranit. Tento kód jsem převzal, takže s ním nejsem úplně podrobně seznámen.
Myslel jsi tohle? Nebo ještě něco jinýho? Vlákna používám pouze ke změně jazyka. Viz. níže...
namespace WindowsFormsApplication1
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
/*Updated 8.4.2013*/
//try
//{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
//}
//catch { }
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel();
this.btn_ChangeLanguage = new System.Windows.Forms.Button();
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.Zobraz_Palubka = new System.Windows.Forms.Button();
this.Zobraz_Verzi = new System.Windows.Forms.Button();
this.Zobraz_error = new System.Windows.Forms.Button();
this.Zobraz_Nastaveni = new System.Windows.Forms.Button();
this.Zobraz_TestIO = new System.Windows.Forms.Button();
this.Zobraz_monitor = new System.Windows.Forms.Button();
this.statusStrip1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.SuspendLayout();
//
// statusStrip1
//
this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripStatusLabel1});
resources.ApplyResources(this.statusStrip1, "statusStrip1");
this.statusStrip1.Name = "statusStrip1";
//
// toolStripStatusLabel1
//
this.toolStripStatusLabel1.Name = "toolStripStatusLabel1";
resources.ApplyResources(this.toolStripStatusLabel1, "toolStripStatusLabel1");
//
// btn_ChangeLanguage
//
this.btn_ChangeLanguage.Image = global::WindowsFormsApplication1.Properties.Resources.flag_cze_mini;
resources.ApplyResources(this.btn_ChangeLanguage, "btn_ChangeLanguage");
this.btn_ChangeLanguage.Name = "btn_ChangeLanguage";
this.btn_ChangeLanguage.UseVisualStyleBackColor = true;
this.btn_ChangeLanguage.Click += new System.EventHandler(this.btn_ChangeLanguage_Click);
this.btn_ChangeLanguage.MouseEnter += new System.EventHandler(this.Zobraz_Nastaveni_MouseEnter);
this.btn_ChangeLanguage.MouseLeave += new System.EventHandler(this.Zobraz_Nastaveni_MouseLeave);
//
// pictureBox1
//
this.pictureBox1.BackColor = System.Drawing.Color.Transparent;
this.pictureBox1.Image = global::WindowsFormsApplication1.Properties.Resources.trojuhelnik;
resources.ApplyResources(this.pictureBox1, "pictureBox1");
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.TabStop = false;
//
// Zobraz_Palubka
//
this.Zobraz_Palubka.Image = global::WindowsFormsApplication1.Properties.Resources.tachometr_mini;
resources.ApplyResources(this.Zobraz_Palubka, "Zobraz_Palubka");
this.Zobraz_Palubka.Name = "Zobraz_Palubka";
this.Zobraz_Palubka.UseVisualStyleBackColor = true;
this.Zobraz_Palubka.Click += new System.EventHandler(this.Zobraz_Click);
this.Zobraz_Palubka.MouseEnter += new System.EventHandler(this.Zobraz_Nastaveni_MouseEnter);
this.Zobraz_Palubka.MouseLeave += new System.EventHandler(this.Zobraz_Nastaveni_MouseLeave);
//
// Zobraz_Verzi
//
this.Zobraz_Verzi.Image = global::WindowsFormsApplication1.Properties.Resources.info_mini;
resources.ApplyResources(this.Zobraz_Verzi, "Zobraz_Verzi");
this.Zobraz_Verzi.Name = "Zobraz_Verzi";
this.Zobraz_Verzi.UseVisualStyleBackColor = true;
this.Zobraz_Verzi.Click += new System.EventHandler(this.Zobraz_Click);
this.Zobraz_Verzi.MouseEnter += new System.EventHandler(this.Zobraz_Nastaveni_MouseEnter);
this.Zobraz_Verzi.MouseLeave += new System.EventHandler(this.Zobraz_Nastaveni_MouseLeave);
//
// Zobraz_error
//
this.Zobraz_error.Image = global::WindowsFormsApplication1.Properties.Resources.error1_mini;
resources.ApplyResources(this.Zobraz_error, "Zobraz_error");
this.Zobraz_error.Name = "Zobraz_error";
this.Zobraz_error.UseVisualStyleBackColor = true;
this.Zobraz_error.Click += new System.EventHandler(this.Zobraz_Click);
this.Zobraz_error.MouseEnter += new System.EventHandler(this.Zobraz_Nastaveni_MouseEnter);
this.Zobraz_error.MouseLeave += new System.EventHandler(this.Zobraz_Nastaveni_MouseLeave);
//
// Zobraz_Nastaveni
//
this.Zobraz_Nastaveni.Image = global::WindowsFormsApplication1.Properties.Resources.settings_mini;
resources.ApplyResources(this.Zobraz_Nastaveni, "Zobraz_Nastaveni");
this.Zobraz_Nastaveni.Name = "Zobraz_Nastaveni";
this.Zobraz_Nastaveni.UseVisualStyleBackColor = true;
this.Zobraz_Nastaveni.Click += new System.EventHandler(this.Zobraz_Click);
this.Zobraz_Nastaveni.MouseEnter += new System.EventHandler(this.Zobraz_Nastaveni_MouseEnter);
this.Zobraz_Nastaveni.MouseLeave += new System.EventHandler(this.Zobraz_Nastaveni_MouseLeave);
//
// Zobraz_TestIO
//
this.Zobraz_TestIO.Image = global::WindowsFormsApplication1.Properties.Resources.testIO_mini;
resources.ApplyResources(this.Zobraz_TestIO, "Zobraz_TestIO");
this.Zobraz_TestIO.Name = "Zobraz_TestIO";
this.Zobraz_TestIO.UseVisualStyleBackColor = true;
this.Zobraz_TestIO.Click += new System.EventHandler(this.Zobraz_Click);
this.Zobraz_TestIO.MouseEnter += new System.EventHandler(this.Zobraz_Nastaveni_MouseEnter);
this.Zobraz_TestIO.MouseLeave += new System.EventHandler(this.Zobraz_Nastaveni_MouseLeave);
//
// Zobraz_monitor
//
this.Zobraz_monitor.Image = global::WindowsFormsApplication1.Properties.Resources.line_graph_icon_mini;
resources.ApplyResources(this.Zobraz_monitor, "Zobraz_monitor");
this.Zobraz_monitor.Name = "Zobraz_monitor";
this.Zobraz_monitor.UseVisualStyleBackColor = true;
this.Zobraz_monitor.Click += new System.EventHandler(this.Zobraz_Click);
this.Zobraz_monitor.MouseEnter += new System.EventHandler(this.Zobraz_Nastaveni_MouseEnter);
this.Zobraz_monitor.MouseLeave += new System.EventHandler(this.Zobraz_Nastaveni_MouseLeave);
//
// Form1
//
resources.ApplyResources(this, "$this");
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.btn_ChangeLanguage);
this.Controls.Add(this.pictureBox1);
this.Controls.Add(this.Zobraz_Palubka);
this.Controls.Add(this.Zobraz_Verzi);
this.Controls.Add(this.Zobraz_error);
this.Controls.Add(this.statusStrip1);
this.Controls.Add(this.Zobraz_Nastaveni);
this.Controls.Add(this.Zobraz_TestIO);
this.Controls.Add(this.Zobraz_monitor);
this.Name = "Form1";
this.statusStrip1.ResumeLayout(false);
this.statusStrip1.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button Zobraz_monitor;
private System.Windows.Forms.Button Zobraz_Nastaveni;
private System.Windows.Forms.StatusStrip statusStrip1;
private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1;
private System.Windows.Forms.Button Zobraz_TestIO;
private System.Windows.Forms.Button Zobraz_error;
private System.Windows.Forms.Button Zobraz_Verzi;
private System.Windows.Forms.Button Zobraz_Palubka;
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.Button btn_ChangeLanguage;
}
}
Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("en");
drbohlav.lukas:8.4.2013 15:38
Už jsem zkoušel z toho form1 smazat ty vlákna, zatím to běží bez
chyby, tak uvidíme. Kód formu máš tady, tak kdybys na něco přišel budu
jedině rád
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Resources;
using System.Globalization;
using System.Reflection;
/*Updated 28.3.2013*/
//using System.Threading;
namespace WindowsFormsApplication1
{
/*Ukazatele na metody (mohou ukazovat na více metod).
*Mohou ukazovat pouze na metody se stejnou signaturou = stejný návratový typ a stejné parametry.*/
public delegate void MyStringDelegate(string text);
public delegate void MyStringBoolDelegate(string text, bool b);
public delegate void MyObjectDelegate(object send);
public delegate void MyComunicateDelegate(Global.Comunication.Com_Data data);
public partial class Form1 : Form
{
List<MyControl> Prvky;
List<Button> Navigation_Button;
Comunication_data_hendler data_hendler;
Comunication comunication;
public event MyComunicateDelegate New_data_recieve;
Random random;
MyControl monitor_c;
MyControl palubka_c;
MyControl nastaveni_c;
MyControl verze_c;
MyControl test_c;
MyControl error_c;
/*Updated 28.3.2013*/
ResourceManager rm = new ResourceManager(typeof(Form1));
public Form1()
{
InitializeComponent();
data_hendler = new Comunication_data_hendler();
data_hendler.Location=new Point(50,50);
data_hendler.Size = new Size(1, 1);
Controls.Add(data_hendler);
data_hendler.TextChanged += new EventHandler(Recieve_data);
random= new Random();
Global.Log.label = toolStripStatusLabel1;
Global.Log.strip = statusStrip1;
Global.Log.Show_Message("");
this.Size = new Size(800,640);
ResourceManager res=new ResourceManager("WindowsFormsApplication1.Resources.obecne_hlasky", Assembly.GetExecutingAssembly());
monitor_c = new Monitor();
palubka_c = new Palubka();
nastaveni_c=new Nastaveni();
verze_c=new Version();
test_c=new TestIO();
error_c = new Error(); ;
Prvky = new List<MyControl>();
Prvky.Add(monitor_c);
Prvky.Add(nastaveni_c);
Prvky.Add(test_c);
Prvky.Add(verze_c);
Prvky.Add(error_c);
Prvky.Add(palubka_c);
/*Protože je palubka_c potomek třídy MyControls, musí se přetypovat na typ Palubka.
*Prijem_dat_start_click - delegát, do kterého se uloží odkaz na metodu ve Form1 Form1_Prijem_dat_start_click.*/
((Palubka)palubka_c).Prijem_dat_start_click += new MyStringBoolDelegate(Form1_Prijem_dat_start_click);
/*Protože je monitor_c potomek třídy MyControls, musí se přetypovat na typ Monitor.
*Zobraz_chybovy_trojuhelnik - delegát, do kterého se uloží odkaz na metodu ve Form1 Form1_Zobraz_chybovy_trojuhelnik.*/
((Monitor)monitor_c).Zobraz_chybovy_trojuhelnik += new MyObjectDelegate(Form1_Zobraz_chybovy_trojuhelnik);
/*Protože je monitor_c potomek třídy MyControls, musí se přetypovat na typ Monitor.
*Prijem_change - delegát, do kterého se uloží odkaz na metodu ve Form1 Form1_Prijem_change.*/
((Monitor)monitor_c).Prijem_change += new MyStringBoolDelegate(Form1_Prijem_change);
comunication = new Comunication(res);
/*Communication.new_data_receive - delegát, do kterého se uloží odkaz na metoru ve Form1 comunication_new_data_recieve.*/
comunication.new_data_recieve += new MyComunicateDelegate(comunication_new_data_recieve);
for (int i = 0; i < Prvky.Count; i++)
{
/*Updated 8.4.2013*
*5 -> 20 */
Prvky[i].Location = new Point(20, 30);
Prvky[i].Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
/*New_data_receive - delegát, do kterého se uloží odkaz na metodu Receive_data v MyControls.
*Tato metoda je virtuální, takže jí lze přetížit u potomka třídy MyControls.*/
this.New_data_recieve += new MyComunicateDelegate(Prvky[i].Recieve_data);
/*Prvky[i].send_data - delegát, do kterého se uloží odkaz na metodu send ve třídě Communication*/
Prvky[i].send_data += new MyComunicateDelegate(comunication.send);
Prvky[i].Set_Resource(res);
this.Controls.Add(Prvky[i]);
}
Navigation_Button = new List<Button>();
Navigation_Button.Add(Zobraz_monitor);
Navigation_Button.Add(Zobraz_Nastaveni);
Navigation_Button.Add(Zobraz_TestIO);
Navigation_Button.Add(Zobraz_Verzi);
Navigation_Button.Add(Zobraz_error);
Navigation_Button.Add(Zobraz_Palubka);
pictureBox1.Visible = false;
this.Zobraz("Zobraz_Palubka");
/*Updated 28.3.2013*/
/*Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("en");
RefreshText();
btn_ChangeLanguage.Text = "CZ";
Language.Actual = "EN";*/
}
void Form1_Prijem_change(string text, bool b)
{
((Palubka)palubka_c).Prijem_change(b);
}
void Form1_Zobraz_chybovy_trojuhelnik(object send)
{
bool zobraz = (bool)send;
if (zobraz)
{
pictureBox1.Visible = true;
}
else {
pictureBox1.Visible = false;
}
}
void Form1_Prijem_dat_start_click(string text, bool b)
{
((Monitor)monitor_c).Prijem_dat_start(b);
}
/*Volá se z: Comunication.cs*/
void comunication_new_data_recieve(Global.Comunication.Com_Data data)
{
/*vrací kladné náhodné číslo*/
string y = random.Next().ToString();
/*Indikace, že volající musí zavolat Invoke metodu, když volá metodu k objektu, protože je volající na jiném vláknu, než objekt*/
if (this.data_hendler.InvokeRequired)
{
/*Vyvolá specifického delegáta na vlákně, které vlastní ovládání objektu*/
/*Action() - delegát, zabalí metodu, která nemá parametry a nevrací žádnou hodnotu*/
data_hendler.Invoke(new Action(() =>
{
this.data_hendler.data = data;
/*data_hendler je potomek labelu, metody obsluhující příjem dat jsou vykonány v momentě, kdy dojde ke změně textu*/
/*uložení náhodného stringu do textu labelu data_hendler*/
this.data_hendler.Text = y;
}));
}
else {
this.data_hendler.data = data;
this.data_hendler.Text = y;
}
}
private void Zobraz_Click(object sender, EventArgs e)
{
Button item = (Button)sender;
Zobraz(item.Name);
}
public void Zobraz(string jmeno) {
Show_Navigation(true);
Style_ALL_Button(jmeno);
switch (jmeno)
{
case "Zobraz_monitor":
this.Zobraz_Zmena("Monitor");
break;
case "Zobraz_Nastaveni":
this.Zobraz_Zmena("Nastaveni");
break;
case "Zobraz_Uvod":
Show_Navigation(false);
this.Zobraz_Zmena("Uvod");
break;
case "Zobraz_TestIO":
this.Zobraz_Zmena("TestIO");
break;
case "Zobraz_Verzi":
this.Zobraz_Zmena("Version");
break;
case "Zobraz_error":
this.Zobraz_Zmena("Error");
break;
case "Zobraz_Palubka":
this.Zobraz_Zmena("Palubka");
break;
default:
this.Zobraz_Zmena(null);
break;
}
}
private void Zobraz_Zmena(string jmeno) {
for (int i = 0; i < Prvky.Count; i++) {
Prvky[i].Visible = false;
Prvky[i].Visible_Change(jmeno,false);
if (jmeno == Prvky[i].Name)
{
string text2 = "";
string text = "";
if (Language.Actual == "CZ")
{
if (jmeno == "Monitor")
text = "Monitor provozních hodnot";
else if (jmeno == "Nastaveni")
text = "Nastavení";
else if (jmeno == "Uvod")
text = "Úvod";
else if (jmeno == "TestIO")
text = "Test akčních členů";
else if (jmeno == "Version")
text = "O verzi";
else if (jmeno == "Error")
text = "Výpis chyb DM1";
else if (jmeno == "Palubka")
text = "Palubní deska";
text2 = "Zobrazuji záložku ";
}
else
{
if (jmeno == "Monitor")
text = "Operational Parameters";
else if (jmeno == "Nastaveni")
text = "Settings";
else if (jmeno == "Uvod")
text = "Welcome";
else if (jmeno == "TestIO")
text = "Actuator Test";
else if (jmeno == "Version")
text = "About Version";
else if (jmeno == "Error")
text = "DM1 Error List";
else if (jmeno == "Palubka")
text = "DashBoard";
text2 = "Show ";
}
Global.Log.Show_Message(text2 + text);
Prvky[i].Visible = true;
Prvky[i].Visible_Change(jmeno,true);
}
}
}
private void Show_Navigation(bool status)
{
for (int i = 0; i < Navigation_Button.Count; i++)
Navigation_Button[i].Visible = status;
}
private void Style_ALL_Button(string actived)
{
for (int i = 0; i < Navigation_Button.Count; i++)
{
if (Navigation_Button[i].Name == actived)
{
Navigation_Button[i].Enabled = false;
}
else
{
Navigation_Button[i].Enabled = true;
Navigation_Button[i].BackColor = SystemColors.Control;
}
}
}
private void Recieve_data(object sender, EventArgs e)
{
data_hendler.pocet++;
New_data_recieve(data_hendler.data);
}
private void Zobraz_Nastaveni_MouseEnter(object sender, EventArgs e)
{
Button but = (Button)sender;
but.BackColor = Color.BurlyWood;
but.Font = new Font(((Button)sender).Font, FontStyle.Regular);
}
private void Zobraz_Nastaveni_MouseLeave(object sender, EventArgs e)
{
Button but = (Button)sender;
but.BackColor = Button.DefaultBackColor;
but.Font = new Font(((Button)sender).Font, FontStyle.Regular);
}
/* private void btn_ChangeLanguage_Click(object sender, EventArgs e)
{
string text = btn_ChangeLanguage.Text;
if (text == "EN")
{
Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("en");
btn_ChangeLanguage.Text = "CZ";
btn_ChangeLanguage.Image = ((System.Drawing.Image)(Properties.Resources.flag_cze_mini));
Global.Log.Show_Message("Language changed to English");
}
else if (text == "CZ")
{
Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("cs");
btn_ChangeLanguage.Text = "EN";
btn_ChangeLanguage.Image = ((System.Drawing.Image)(Properties.Resources.british_flag_mini));
Global.Log.Show_Message("Jazyk změněn na Český jazyk");
}
RefreshText();
Language.Actual = text;
((Palubka)palubka_c).ChangeLanguage(text);
((Monitor)monitor_c).ChangeLanguage(text);
((TestIO)test_c).ChangeLanguage(text);
((Error)error_c).ChangeLanguage(text);
((Version)verze_c).ChangeLanguage(text);
((Nastaveni)nastaveni_c).ChangeLanguage(text);
}
private void RefreshText()
{
Zobraz_Palubka.Text = rm.GetString("Zobraz_Palubka.Text");
Zobraz_monitor.Text = rm.GetString("Zobraz_monitor.Text");
Zobraz_TestIO.Text = rm.GetString("Zobraz_TestIO.Text");
Zobraz_error.Text = rm.GetString("Zobraz_error.Text");
Zobraz_Verzi.Text = rm.GetString("Zobraz_Verzi.Text");
Zobraz_Nastaveni.Text = rm.GetString("Zobraz_Nastaveni.Text");
this.Text = rm.GetString("$this.Text");
}*/
}
}
paanoik:15.4.2013 11:23
Sorry, že vytahuju x dní starý vlákno.
Cross thread exception je plošně "chyba designu synchronizace vláken". Kód jsem do detailu nepřelouskával, ale v základu, když si například v hlavním vlákně vytvoříš background workera, tak mu nemůžeš jednoduše předat odkaz na to hlavní vlákno(form) a měnit si tam věci v gui. Tedy, tohle fungovalo někdy v první verzi VS2003, od té doby to VS nepustí přes kompilátor.
Pokud chceš komunikovat mezi vlákny, musíš k tomu použít eventy vždy, tedy jestli ti to padá v konkrétním místě, odkrokuj do něj, projdi seznam lokálních proměnných a prověř, jestli tam někde nemáš třeba pověšený event, který spadá k jinému vláknu (třeba pověšený dispose formu na dispose démona).
Zobrazeno 6 zpráv z 6.