In Silverlight/WPF, if you want to modify the interface control value in multiple threads, The begininvoke method of the dispatcher object is undoubtedly the most convenient method. For details, refer: how to update the value of the UI control in winform/Silverlight multi-thread programming
However, it is found today that begininvoke in WPF cannot automatically convert anonymous methods/lambda expressions to the delegate type (Note: friends who are unfamiliar with delegation, anonymous methods, and Lambda should first read the story and learn about it: Delegate, action, func, anonymous method, anonymous delegate, event)
In SilverlightCodeFragment:
Private void button#click (Object sender, routedeventargs e) {thread t = new thread (testmethod); T. start (); thread t2 = new thread (testmethod2); t2.start ("Hello World");} void testmethod () {This. dispatcher. begininvoke () => {This. textblock1.text = datetime. now. tostring ("HH: mm: SS") ;}) ;}void testmethod2 (Object s) {This. dispatcher. begininvoke () => {This. textblock1.text = S. tostring ();});}
If this is used in WPF, the following error is reported:
Cannot convert Lambda expression to type 'System. Delegate 'because it is not a delegate type
That is, the lambda expression cannot be converted to "system. Delegate" because it is not of the delegate type.
Not even if Lambda expressions are changed to anonymous methods:
Public void testmethod () {This. Dispatcher. begininvoke (delegate () {This. textblock1.text = datetime. Now. tostring ("HH: mm: SS fff ");});}
An error will still be reported:
Cannot convert anonymous method to type 'System. delegate' because it is not a delegate type
That is, the anonymous method cannot be converted to "system. Delegate" because it is not of the delegate type.
Of course, you can also define a delegate type and write it in the most traditional way:
Delegate void mydelegate (); Delegate void mydelegate2 (Object S); Public void testmethod () {mydelegate d = new mydelegate (updatetext); this. dispatcher. begininvoke (d);} void updatetext () {This. textblock1.text = datetime. now. tostring ("HH: mm: SS fff");} void updatetext2 (Object s) {This. textblock1.text = S. tostring ();} public void testmethod2 (Object s) {mydelegate2 d = new mydelegate2 (updatetext2); this. dispatcher. begininvoke (d, "Hello World ");}
However, this writing method is too cumbersome. We have to extract the definition of the method separately and define the corresponding delegate type. Isn't it as refreshing as in silverlght?
Since the cause of the error is that the compiler does not automatically perform type conversion, Let's force the conversion.
Public void testmethod () {This. dispatcher. begininvoke (Action) Delegate () {This. textblock1.text = datetime. now. tostring ("HH: mm: SS fff") ;}) ;}public void testmethod2 (Object s) {This. dispatcher. begininvoke (action) () => {This. textblock1.text = S. tostring ();}));}
In this way, the anonymous method/Lambda expression is forcibly converted to action, and the essence of action is the delegate type, so. The problem is solved!
But I still have some questions: why can the compiler automatically identify Silverlight, but not WPF? This is not a bug in the compiler (or something to be improved)