0

I'm going to implement MVC structure of delegate same like in Objective-C. Basically my functionality is like Bluetooth device return me signal i grab it in C++ Callback and that signal message i going to forward to callback of C# lambda function. I got following error,

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

My C# code Form1.cs,

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
    delegate void ProgressCallback(char theValue);

private void button1_Click(object sender, EventArgs e)
        {
             if (NclWrapper.isNclInitialized())
                {
                    NclWrapper.callNclDiscovery();
                    label1.Text = NclWrapper.getLedPattern();

                    ProgressCallback callback = (theValue) =>
                    {
                      //Crash is here when i going to assign value to lable.
                        this.label1.Text = theValue.ToString();
                        Console.WriteLine("Progress = {0}", theValue);
                    };
                    NclWrapper.DoWork(callback);
                 }
            }
        }

My C++ DLL wrapper in C#

[DllImport("My.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
    public static extern void DoWork([MarshalAs(UnmanagedType.FunctionPtr)] ProgressCallback callbackPointer);

My C++ .cpp class delegate assignment,

 ProgressCallback myDelegateObject;
    __declspec(dllexport) void DoWork(ProgressCallback progressCallback)
    {
            if (progressCallback)
            {
              myDelegateObject = progressCallback;
            }
    }

My C++ sending callback message

void callback(MyEvent event, void* userData){

    wchar_t  ch[6];
    ULONG  ulSize;
    switch(event.type){
/// [callbackInit]
    case MY_EVENT_INIT:
            if(event.init.success) gMyInitialized=true;
            else exit(-1);
            prevEvent = event.type; 
            break;
/// [callbackAgreement]
        case My_EVENT_AGREEMENT:
            gHandle=event.agreement.myHandle;
            for(unsigned i=0; i<My_AGREEMENT_PATTERNS; ++i){
                for(unsigned j=0; j<My_LEDS; ++j){
                    if(event.agreement.leds[i][j]){
                        ch[j]='1';
                    }else{
                        ch[j]='0';
                    }
                }
                std::cout<<"\n";
            }
            ch[5]='\0';
            ulSize = (wcslen(ch) * sizeof(wchar_t)) + sizeof(wchar_t);
            ledPattern = NULL;
            ledPattern = (wchar_t*)::CoTaskMemAlloc(ulSize);
            wcscpy(ledPattern, ch);
            prevEvent = event.type;

            //My delegate callback is here
            myDelegateObject('D');
            break;

        default: break;
    }

}

where i'm wrong?

Tirth
  • 7,801
  • 9
  • 55
  • 88
  • Try wrap `this.label1.Text = theValue.ToString();` with `Dispatcher.Invoke();` – Diligent Key Presser Dec 02 '14 at 08:20
  • possible duplicate of [Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on](http://stackoverflow.com/questions/142003/cross-thread-operation-not-valid-control-accessed-from-a-thread-other-than-the) – Peter Duniho Dec 02 '14 at 08:51
  • @Peter Duniho, dude error is similar but way of implementation is different ...I guess this isn't duplicate question. BTW I'm asking where I'm wrong. – Tirth Dec 02 '14 at 09:00
  • It is absolutely the same problem. Just because you took a roundabout way to get to the exception, that doesn't change the fact that the problem and the solution are both the same: you need to execute the code in the UI thread, and the way to do that is explained in the duplicate question. – Peter Duniho Dec 02 '14 at 09:05
  • @PeterDuniho sorry dude. but i not seen clear picture of my solution through your given link. Can you help me how i implement Invoke method in lambda function? – Tirth Dec 02 '14 at 09:18
  • One time i was thinking about invoke method but if it implement same in C# class, i wanting cross language message passing. I want capture C++ callback event or message capture in C#. – Tirth Dec 02 '14 at 09:25

1 Answers1

0
 ProgressCallback callback = (theValue) =>
                    {
                        label1.Invoke((MethodInvoker)delegate {
                             label1.Text = theValue.ToString();
                        });
                    };

This code stuff update my label text.

Tirth
  • 7,801
  • 9
  • 55
  • 88