Avatar billede cooraz Nybegynder
07. maj 2010 - 22:34 Der er 8 kommentarer og
2 løsninger

problem med exception (cross-thread operation)

jeg har et problem med mit visual C++ projekt

jeg har en class.cpp fil og .h fil og self min form1.h

fejlen sker når jeg fra min class.cpp kalder en tekstboks(servo1position) i form1 for at ville ændre teksten i den...

her er fejlen:
An unhandled exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll

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

i form1 er servo1position defineret sådan:
public: static System::Windows::Forms::TextBox^  Servo1position;

og i class.cpp filen ser det sådan ud:
eyeRwindows::Form1::Servo1position->Text = S1;

evt mere info kan gives hvis det er nødvendigt...
Avatar billede arne_v Ekspert
07. maj 2010 - 23:11 #1
Naar du skal opdatere en Win Form GUI control fra andet en event traaden, saa skal du bruge Invoke.
Avatar billede cooraz Nybegynder
08. maj 2010 - 16:46 #2
hmm okay, jeg har ikke brugt invoke før, hvordan bruger man den?

jeg er kommet frem til at jeg vidst skal oprette en delegate i form1.h:

public: delegate void test_delegate();

og så er jeg i tvivl om hvordan jeg gør inde i class filen...
er det noget i den stil ( hvad skal der så stå i parentesen?)

eyeRwindows::Form1::test_delegate^ d;
d += gcnew eyeRwindows::Form1::test_delegate();
d->invoke();
Avatar billede arne_v Ekspert
09. maj 2010 - 02:15 #3
Hvorfor pokker laver du win forms kode i C++??

Nå men - her er et eksempel på invoke.

Kode som ikke virker:

    private:
        void UpdateLabel()
        {
            label1->Text = DateTime::Now.ToString();
        }
        void StartCounter()
        {
            for(int i = 0; i < 10; i++)
            {
                Thread::Sleep(1000);
                                UpdateLabel();
            }
        }
        void Form1_Load(Object^ sender, EventArgs^ e)
        {
            UpdateLabel();
            Thread^ t = gcnew Thread( gcnew ThreadStart( this, &Form1::StartCounter ) );
            t->Start();
        }
    };

i form load starter vi en tråd som forsøger at opdatere en label.

Den går ikke fordi opdateringer af GUI skal ske fra event tråden.

    private:
        delegate void Handler();
        void UpdateLabel()
        {
            label1->Text = DateTime::Now.ToString();
        }
        void StartCounter()
        {
            for(int i = 0; i < 10; i++)
            {
                Thread::Sleep(1000);
                label1->Invoke(gcnew Handler(this, &Form1::UpdateLabel));
            }
        }
        void Form1_Load(Object^ sender, EventArgs^ e)
        {
            UpdateLabel();
            Thread^ t = gcnew Thread( gcnew ThreadStart( this, &Form1::StartCounter ) );
            t->Start();
        }
    };

virker som det skal fordi der bruges Invoke.
Avatar billede cooraz Nybegynder
09. maj 2010 - 20:28 #4
fordi jeg ikke kender det helt vilde til c#...

okay det vil jeg lige kigge lidt nærmere på :)
Avatar billede cooraz Nybegynder
11. maj 2010 - 23:32 #5
jeg har fået det til at virke, men hvad hvis jeg skal have noget tekst sendt med fra min class fil til update funktionen?

altså så burde den jo være
label1->Invoke(gcnew Handler(this, &Form1::UpdateLabel("input tekst"));

men det kan den ikke rigtig lide... ville det evt være bedre bare og sætte en public variabel i min class fil som kan læses fra min form1 fil? eller er der en smartere måde at gøre det på?
Avatar billede arne_v Ekspert
12. maj 2010 - 01:52 #6
Prøv med:

delegate void Handler(String^ s);
...
        void UpdateLabel(String^ s)
        {
            label1->Text = s;
        }
...
array<Object^>^ arg = gcnew array<Object^>(1);
arg[0] = L"Bla bla bla";
label1->Invoke(gcnew Handler(this, &Form1::UpdateLabel), arg);
Avatar billede cooraz Nybegynder
12. maj 2010 - 15:06 #7
den compiler fint, men giver den her fejl når funktionen bliver kaldt:
A first chance exception of type 'System.ArgumentException' occurred in mscorlib.dll
A first chance exception of type 'System.ArgumentException' occurred in System.Windows.Forms.dll
An unhandled exception of type 'System.ArgumentException' occurred in System.Windows.Forms.dll

Additional information: Object of type 'System.Object[]' cannot be converted to type 'System.String'.



hvorfor er det at visual studio nogle gange fjerne static foran mine textboxes? altså hvis jeg skriver:
public: static System::Windows::Forms::TextBox^  pwn1position;

kan den finde på at ændre det til
public: System::Windows::Forms::TextBox^  pwn1position;

er det noget jeg kan slå fra et sted eller hvad?
Avatar billede cooraz Nybegynder
19. maj 2010 - 23:49 #8
har fået det til at virke
skriv et svar så får du point
Avatar billede arne_v Ekspert
20. maj 2010 - 02:05 #9
OK
Avatar billede arne_v Ekspert
20. maj 2010 - 02:05 #10
OK
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester