{"id":298,"date":"2012-06-28T16:16:10","date_gmt":"2012-06-28T15:16:10","guid":{"rendered":"http:\/\/www.kolja-engelmann.de\/blog\/?p=298"},"modified":"2012-06-28T16:16:10","modified_gmt":"2012-06-28T15:16:10","slug":"c-invoke-required-durch-lambda-ausruck-verschonert","status":"publish","type":"post","link":"https:\/\/www.kolja-engelmann.de\/blog\/2012\/06\/c-invoke-required-durch-lambda-ausruck-verschonert\/","title":{"rendered":"C# &#8211; Invoke required durch Lambda Ausruck versch\u00f6nert"},"content":{"rendered":"<p>Passiert mir immer mal wieder. Ich versuche die Inhalte eines Controls aus einem anderen Thread heraus zu ver\u00e4ndern als aus dem, der das Control urpsr\u00fcnglich mal erzeugte. Was dabei heraus kommt ist klar: <code>The calling thread cannot access this object because it is owned by another thread.<\/code> Ich muss also folglich meinen Code im Kontext des Threads ausf\u00fchren, der das Control erstellte. Bis dato nutzte ich immer folgendes Snippet:<\/p>\n<pre class=\"lang:c# decode:true\">this.Dispatcher.Invoke(\r\n    new Action(\r\n        delegate()\r\n        {\r\n            \/\/ Do your code here\r\n            MessageBox.Show(\"Invoke succeeded\");\r\n        }\r\n    )\r\n);<\/pre>\n<p>Wann immer dieser Codeblock erreicht wird, werden die folgenden Anweisungen im Kontext des UI-Threads ausgef\u00fchrt. Das klappte bisher immer ganz gut und ich nutzte es z.B. immer dann wenn ich Debug-Meldungen zu meinem Debug-Listener-Dialog sandte. Leider scheint diese Methode ziemlich &#8222;teuer&#8220; zu sein. Als ich heute einmal an einem langsameren Rechner arbeitete und mehrere Debugmeldungen pro Sekunde absetzte, ging die Performance des Programms doch stark in die Knie. Ein kurzes Profiling sprach B\u00e4nde, <code>Invoke<\/code> ist schweinelahm, besonders wenn es, wie in diesem Fall gar nicht notwendig gewesen w\u00e4re. Zum Gl\u00fcck gibt es f\u00fcr WPF die M\u00f6glichkeit f\u00fcr jedes Control das Feld <code>InvokeRequired<\/code> abzufragen welches angibt, ob sich die Programmausf\u00fchrung gerade in dem Thread befindet, der das Control erstellt hat. Somit k\u00f6nnte ich also folgenden Code ausf\u00fchren:<\/p>\n<pre class=\"lang:c# decode:true\">if (this.Dispatcher.CheckAccess())\r\n{\r\n    \/\/ Your Invoked Code\r\n}\r\nelse\r\n{\r\n    \/\/ Your code without invoking\r\n}<\/pre>\n<p>Das funktioniert zwar, aber ich m\u00fcsste ja meinen Code zweimal tippen und pflegen&#8230;unsch\u00f6n. Zur L\u00f6sung des Problemchens entschied ich mich f\u00fcr Lambda-Ausdr\u00fccke, denn so konnte ich meinen Code in einer Variablen zwischenspeichern.<\/p>\n<pre class=\"lang:c# decode:true\">\/\/ Create a function with a string input and a bool return value\r\nFunc&lt;string,bool&gt; handleEvent = (string pMessage) =&gt;\r\n{\r\n\tMessageBox.Show(pMessage);\r\n\treturn true;\r\n};                \r\n\r\n\/\/ Are we running on the correct UI Thread\r\nif (this.Dispatcher.CheckAccess())\r\n{\r\n\t\/\/Directly run the method\r\n\thandleEvent(pMessage);\r\n}\r\nelse\r\n{\r\n\t\/\/ Invoke the method from the UI Thread dispatcher\r\n\tthis.Dispatcher.Invoke(handleEvent,pMessage);\r\n}<\/pre>\n<p>Jetzt l\u00e4uft es so wie ich es mir vorstelle. Versch\u00f6nern, Verk\u00fcrzen und Modularisieren kann man nat\u00fcrlich immernoch.<\/p>\n<p>Done;<\/p>","protected":false},"excerpt":{"rendered":"<p>Passiert mir immer mal wieder. Ich versuche die Inhalte eines Controls aus einem anderen Thread heraus zu ver\u00e4ndern als aus dem, der das Control urpsr\u00fcnglich mal erzeugte. Was dabei heraus kommt ist klar: The calling&#46;&#46;&#46;<\/p>\n","protected":false},"author":1,"featured_media":292,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[38],"tags":[39,40],"class_list":["post-298","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-codeschnippsel","tag-c","tag-wpf"],"jetpack_featured_media_url":"https:\/\/www.kolja-engelmann.de\/blog\/wp-content\/uploads\/2012\/06\/coding_php.jpg","jetpack_sharing_enabled":true,"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.kolja-engelmann.de\/blog\/wp-json\/wp\/v2\/posts\/298","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.kolja-engelmann.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.kolja-engelmann.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.kolja-engelmann.de\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.kolja-engelmann.de\/blog\/wp-json\/wp\/v2\/comments?post=298"}],"version-history":[{"count":0,"href":"https:\/\/www.kolja-engelmann.de\/blog\/wp-json\/wp\/v2\/posts\/298\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.kolja-engelmann.de\/blog\/wp-json\/wp\/v2\/media\/292"}],"wp:attachment":[{"href":"https:\/\/www.kolja-engelmann.de\/blog\/wp-json\/wp\/v2\/media?parent=298"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.kolja-engelmann.de\/blog\/wp-json\/wp\/v2\/categories?post=298"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.kolja-engelmann.de\/blog\/wp-json\/wp\/v2\/tags?post=298"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}