c# - How can I run code inside a Converter on a separate thread so that the UI does not freeze? -


i have wpf converter slow (computations, online fetching, etc.). how can convert asynchronously ui doesn't freeze up? found this, solution place converter code in property - http://social.msdn.microsoft.com/forums/pl-pl/wpf/thread/50d288a2-eadc-4ed6-a9d3-6e249036cb71 - rather not do.

below example demonstrates issue. here dropdown freeze until sleep elapses.

namespace testasync {     using system;     using system.collections.generic;     using system.threading;     using system.windows;     using system.windows.data;     using system.windows.threading;      /// <summary>     /// interaction logic mainwindow.xaml     /// </summary>     public partial class mainwindow : window     {         public mainwindow()         {             initializecomponent();              mynumbers = new dictionary<string, int> { { "uno", 1 }, { "dos", 2 }, { "tres", 3 } };              this.datacontext = this;                    }          public dictionary<string, int> mynumbers         {             { return (dictionary<string, int>)getvalue(mynumbersproperty); }             set { setvalue(mynumbersproperty, value); }         }         public static readonly dependencyproperty mynumbersproperty =             dependencyproperty.register("mynumbers", typeof(dictionary<string, int>), typeof(mainwindow), new uipropertymetadata(null));           public string mynumber         {             { return (string)getvalue(mynumberproperty); }             set { setvalue(mynumberproperty, value); }         }         public static readonly dependencyproperty mynumberproperty = dependencyproperty.register(             "mynumber", typeof(string), typeof(mainwindow), new uipropertymetadata("uno"));     }      public class asyncconverter : imultivalueconverter     {         public object convert(object[] values, type targettype, object parameter, system.globalization.cultureinfo culture)         {             object result = null;               if (values[0] string && values[1] idictionary<string, int>)             {                 doasync(                     () =>                         {                                             thread.sleep(2000); // simulate long task                             var number = (string)(values[0]);                             var numbers = (idictionary<string, int>)(values[1]);                              result = numbers[number];                             result = result.tostring();                         });             }              return result;         }          private void doasync(action action)         {             var frame = new dispatcherframe();             new thread((threadstart)(() =>             {                 action();                 frame.continue = false;             })).start();             dispatcher.pushframe(frame);         }          public object[] convertback(object value, type[] targettype, object parameter, system.globalization.cultureinfo culture)         {             throw new notsupportedexception();         }     } 

and xaml:

<window x:class="testasync.mainwindow"         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"         xmlns:local="clr-namespace:testasync"         title="mainwindow" height="200" width="200">     <window.resources>         <local:asyncconverter x:key="asyncconverter"/>     </window.resources>     <dockpanel>         <combobox dockpanel.dock="top" selecteditem="{binding mynumber, isasync=true}"                                      itemssource="{binding mynumbers.keys, isasync=true}"/>         <textblock datacontext="{binding isasync=true}"             fontsize="50" fontweight="bold" horizontalalignment="center" verticalalignment="center">             <textblock.text>                 <multibinding converter="{staticresource asyncconverter}">                     <binding path="mynumber" isasync="true"/>                     <binding path="mynumbers" isasync="true"/>                 </multibinding>             </textblock.text>         </textblock>     </dockpanel> </window> 

note bindings isasync="true", doesn't help.

enter image description here

the combobox stuck 2000 ms.

i know said don't want invoke translation property setter, submit cleaner approach ivalueconverter/imultivalueconverter.

ultimately, want set value of selected number combobox, , return immediately. want defer updating displayed/translated value until translation process complete.

i think clearer model data such translated value property gets updated asynchronous process.

    <combobox selecteditem="{binding selectednumber, mode=onewaytosource}"                                  itemssource="{binding mynumbers.keys}"/>     <textblock text="{binding mynumbervalue}" /> 

public partial class mainwindow : window, inotifypropertychanged {     public mainwindow()     {         initializecomponent();          mynumbers = new dictionary<string, int> { { "uno", 1 }, { "dos", 2 }, { "tres", 3 } };          datacontext = this;        }      public idictionary<string, int> mynumbers { get; set; }      string _selectednumber;     public string selectednumber     {         { return _selectednumber; }         set         {             _selectednumber = value;             notify("selectednumber");             updatemynumbervalue();         }     }      int _mynumbervalue;     public int mynumbervalue     {         { return _mynumbervalue; }         set          {              _mynumbervalue = value;             notify("mynumbervalue");         }     }      void updatemynumbervalue()     {         var key = selectednumber;         if (key == null || !mynumbers.containskey(key)) return;          new thread(() =>         {             thread.sleep(3000);             mynumbervalue = mynumbers[key];         }).start();     }      public event propertychangedeventhandler propertychanged;     void notify(string property)     {         var handler = propertychanged;         if(handler != null) handler(this, new propertychangedeventargs(property));     } } 

Comments

Popular posts from this blog

c# - SharpSVN - How to get the previous revision? -

c++ - Is it possible to compile a VST on linux? -

url - Querystring manipulation of email Address in PHP -