InvalidOperationException – .NET – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

InvalidOperationException – .NET – Fórum – Programujte.comInvalidOperationException – .NET – Fórum – Programujte.com

 

Matěj Pácha0
Super člen
20. 3. 2007   #1
-
0
-

Mám opět jeden problém. Moje aplikace např. na reakci tlačítka nebo voláním funkce mění parametry dalších prvků, především textboxů. Buď text nebo jejich "ReadOnly property". Pokud aplikaci spustím "Without debugging", jede všechno tak jak má. Ale když se pokusím o Debug, po kliknutí tlačítka a pokusu o změnu parametru textboxu je vyvolána vyjímka InvalidOperationException s dovětkem, že byl proveden pokus o volání (změnu) objektem, který na to nemá právo. Všechno je to jednosouborová záležitost, tj. vše je ve Form.h, v jednom namespace. Nevím, proč by to nemělo jít, když bez debug modu to jde. Chápu, že debug mod je trošku odlišný, ale tohle si myslím že je standardní změna parametrů a měla by být umožněna. Problém je v tom, že se potřebuju dostat právě do debug modu a nechce se mi psát "servisní messageboxy". Neporadil by mi někdo? Možná se dívám na filozofii programování v .NET CLR špatně

Nahlásit jako SPAM
IP: ...–
Ajem tíčr, andrgraund tíčr!
Matěj Pácha0
Super člen
21. 3. 2007   #2
-
0
-

Přidávám výpis chyby:

System.InvalidOperationException: Operace mezi podprocesy není platná: Přístup k ovládacímu prvku textBox1 proběhl z jiného podprocesu než z podprocesu, v rámci kterého byl vytvořen.


Ještě přidám jeden úryvek, který na mě často "bliká":


private: System::Void logMe(String^ log, int cat)
{
logfile = tLogFolderValue->Text + "\\log.txt";
int logcat = 0;
if(rLogFull->Checked)
logcat = 3;
if(rLogMedium->Checked)
logcat = 2;
if(rLogSoft->Checked)
logcat = 1;

//V následujícím řádku se program zastaví (pokud běží v debug modu):
tStatusLabel->Text = log;
tStatusLabel->ForeColor = Color::Black;
tStatusIcon->Visible = false;
tStatusIcon->Invalidate();
if(cat <= logcat)
{
try
{
if(File::Exists(logfile))
File::SetAttributes(logfile,System::IO::FileAttributes::Normal);
StreamWriter ^lw = gcnew StreamWriter(logfile,true);
lw->WriteLine(DateTime::Now); lw->WriteLine(log);
lw->WriteLine("=======================================================");
File::SetAttributes(logfile,FileAttributes::ReadOnly);
}
catch(Exception^ e)
{
logError(e);
tStatusLabel->Text = "Logging error!";
}
finally
{
lw->Close();
}
this->Invalidate();
}
}

Pokud jsem se mýlil, že můžu parametry prvků měnit v metodách třídy, do které patří, tak mi prosím poraďte, jak to UDĚLAT.
Díky

Nahlásit jako SPAM
IP: ...–
Ajem tíčr, andrgraund tíčr!
DeaLer+2
Hero
21. 3. 2007   #3
-
0
-

Ten výpis chybovky je sice fajn, ale je prakticky k ničemu, když je česky (google těžko něco najde a já nevim, kde může být příčina problému).

PS: nemáš tu výjimku někde nějak ošetřenou (debuggeru je to jedno a stejně na ni upozorní)?

Nahlásit jako SPAM
IP: ...–
Dušan Janošík | web: djanosik.cz, @djanosik
Matěj Pácha0
Super člen
21. 3. 2007   #4
-
0
-

To je právě to zvláštní. Ta výjimka se prostě stane. Ano, můžu ji zachytit, ale co s ní? Já potřebuju např. ten text v poli změnit. A když systém zachytí výjimku, skočí na obsluhu výjimky v bloku catch, čímž přeskočí to, co následuje za posledním příkazem a to právě nechci. A zvláštní je, že v případě že to neběží v debug módu, tak výjimka nenastane (protože bych o tom věděl - každou výjimku zapisuju do souboru a když ani to nejde, skáče mi messagebox). Podrobnější výpis můžu přihodit, ale jelikož se jedná o složitější aplikaci (asi jak pro koho), nebude tam tolik čitelné, kde to vzniká. Ačkoliv mě teď napadlo, že pracuju se sériovým portem a ona výjimka se objevuje při volání z funkcí, které pracují se sériovým portem. Ale jak tohle změnit, to bych musel hodně věcí předělat. No a já právě potřebuju vidět po krocích zpracování dat přijatých z portu. Pro doplnění uvádím celou hlášku:


System.InvalidOperationException: Operace mezi podprocesy není platná: Přístup k ovládacímu prvku tPortIsOpenValue proběhl z jiného podprocesu než z podprocesu, v rámci kterého byl vytvořen.
v System.Windows.Forms.Control.get_Handle()
v System.Windows.Forms.Control.set_WindowText(String value)
v System.Windows.Forms.TextBoxBase.set_WindowText(String value)
v System.Windows.Forms.Control.set_Text(String value)
v System.Windows.Forms.TextBoxBase.set_Text(String value)
v System.Windows.Forms.TextBox.set_Text(String value)
v ENO02.Form1.serialPortDataRecieved(Object sender, SerialDataReceivedEventArgs e)


Následuje ještě odkaz na řádek, na kterém program skončil, kde je vložení řetězce do textového pole tPortIsOpenValue.

EDIT:
Např. když posílám testovací message, vypadá to nějak takhle:


private: System::Void bTest_Click(System::Object^ sender, System::EventArgs^ e)
{
//sestavení zprávy, mám vlastní knihovnu na její vytváření
mbData^ mbs = gcnew mbData();
mbs->AddAdress(toSend.CAdress);
mbs->AddFuncCode(0);
mbs->AddSpecAdr(1);
array<int,1>^ msg = gcnew array<int,1>(0);
mbs->AddData(msg);
try
{
//Nastavení a otevření portu, odeslání zprávy
serialPort1->PortName = (String^) cComSelect->SelectedItem;
serialPort1->BaudRate = System::Convert::ToInt32(cBaudRate->SelectedItem);
serialPort1->Open();
serialPort1->Write(mbs->Send(),0,mbs->Length);
logMe(text.recieverequestsent,2);
//Nastavení textboxů jako informace pro uživatele, že se něco děje - tady se v debug modu objeví výjimka
tConnectionStatus->Text = text.connecting;
tPortIsOpenValue->Text = Convert::ToString(serialPort1->IsOpen);
tPortIsOpenValue->Invalidate();
}
catch(Exception^ e)
{
logError(e);
serialPort1->Close();
tPortIsOpenValue->Text = Convert::ToString(serialPort1->IsOpen);
tPortIsOpenValue->Invalidate();
}
//Za normálních okolností se o zavření portu stará obsluha přerušení (zprávy) SerialDataRecieved
return;
}

Nahlásit jako SPAM
IP: ...–
Ajem tíčr, andrgraund tíčr!
DeaLer+2
Hero
22. 3. 2007   #5
-
0
-

Tak to se asi budeš muset zeptat nějakýho profíka - určitě to někdo řešil.

Nahlásit jako SPAM
IP: ...–
Dušan Janošík | web: djanosik.cz, @djanosik
Matěj Pácha0
Super člen
22. 3. 2007   #6
-
0
-

Tak už jsem to našel. Sice to musím ještě pořádně přelouskat, ale je tam odpověď. Ono totiž okno jako takové není Multithread, ale prvky, které jsem použil z něj multithread dělají - serialPort a Timer. Když se z nich pokouším měnit prvky v okně, sahám do jiného threadu, což se projeví výjimkou, která v debug modu vyskočí vždy, v run time jen někdy. Tady je odkaz na msdn:
http://msdn2.microsoft.com/en-us/library/ms171728.aspx

Nahlásit jako SPAM
IP: ...–
Ajem tíčr, andrgraund tíčr!
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 3 hosté

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý