标签:
这里是一张动画,演示在多线程(无限循环+Thread.Sleep)情况下主界面操作不受影响。1 2 3 4 5 6 7 8 9 10 11 | public void DoWork() { if (control.InvokeRequired) { control.Invoke(DoWork); } else { // do work } } |
1 | InvokeHelper.Invoke(<控件>, "<方法名称>" , <参数>); |
1 | InvokeHelper.Get(<控件>, "<属性名称>" ); |
1 | InvokeHelper.Set(<控件>, "<属性名称>" , <属性值>); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | /******************************************************************************* * InvokeHelper.cs * A thread-safe control invoker helper class. * ----------------------------------------------------------------------------- * Project:Conmajia.Controls * Author:Conmajia * Url:conmajia@gmail.com * History: * 4th Aug., 2012 * Added support for "Non-control" controls (such as ToolStripItem). * * 4th Aug., 2012 * Initiated. ******************************************************************************/ using System; using System.Collections.Generic; using System.Reflection; using System.Text; using System.Windows.Forms; namespace InvokerHelperDemo { /// <summary> /// A thread-safe control invoker helper class. /// </summary> public class InvokeHelper { private delegate object MethodInvoker(Control control, methodName, params object [] args); private delegate object PropertyGetInvoker(Control control, object noncontrol, string propertyName); private delegate void PropertySetInvoker(Control control, object noncontrol, string propertyName, object value); #endregion #region static methods // helpers private static PropertyInfo GetPropertyInfo(Control control, object noncontrol, string propertyName) { if (control != null && ! string .IsNullOrEmpty(propertyName)) { PropertyInfo pi = null ; Type t = null ; if (noncontrol != null ) t = noncontrol.GetType(); else t = control.GetType(); pi = t.GetProperty(propertyName); if (pi == null ) throw new InvalidOperationException( string .Format( "Can‘t find property {0} in {1}." , propertyName, t.ToString() )); return pi; } else throw new ArgumentNullException( "Invalid argument." ); } // outlines public static object Invoke(Control control, string methodName, params object [] args) { if (control != null && ! string .IsNullOrEmpty(methodName)) if (control.InvokeRequired) return control.Invoke( new MethodInvoker(Invoke), control, methodName, args ); else { MethodInfo mi = null ; if (args != null && args.Length > 0) { Type[] types = new Type[args.Length]; for ( int i = 0; i < args.Length; i++) { if (args[i] != null ) types[i] = args[i].GetType(); } mi = control.GetType().GetMethod(methodName, types); } else mi = control.GetType().GetMethod(methodName); // check method info you get if (mi != null ) return mi.Invoke(control, args); else throw new InvalidOperationException( "Invalid method." ); } else throw new ArgumentNullException( "Invalid argument." ); } public static object Get(Control control, string propertyName) { return Get(control, null , propertyName); } public static object Get(Control control, object noncontrol, string propertyName) { if (control != null && ! string .IsNullOrEmpty(propertyName)) if (control.InvokeRequired) return control.Invoke( new PropertyGetInvoker(Get), control, noncontrol, propertyName ); else { PropertyInfo pi = GetPropertyInfo(control, noncontrol, propertyName); object invokee = (noncontrol == null ) ? control : noncontrol; if (pi != null ) if (pi.CanRead) return pi.GetValue(invokee, null ); else throw new FieldAccessException( string .Format( "{0}.{1} is a write-only property." , invokee.GetType().ToString(), propertyName )); return null ; } else throw new ArgumentNullException( "Invalid argument." ); } public static void Set(Control control, string propertyName, object value) { Set(control, null , propertyName, value); } public static void Set(Control control, object noncontrol, string propertyName, object value) { if (control != null && ! string .IsNullOrEmpty(propertyName)) if (control.InvokeRequired) control.Invoke( new PropertySetInvoker(Set), control, noncontrol, propertyName, value ); else { PropertyInfo pi = GetPropertyInfo(control, noncontrol, propertyName); object invokee = (noncontrol == null ) ? control : noncontrol; if (pi != null ) if (pi.CanWrite) pi.SetValue(invokee, value, null ); else throw new FieldAccessException( string .Format( "{0}.{1} is a read-only property." , invokee.GetType().ToString(), propertyName )); } else throw new ArgumentNullException( "Invalid argument." ); } #endregion } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | Thread t; private void button1_Click( object sender, EventArgs e) { if (t == null ) { t = new Thread(multithread); t.Start(); label4.Text = string .Format( "Thread state:\n{0}" , t.ThreadState.ToString() ); } } public void DoWork( string msg) { this .label3.Text = string .Format( "Invoke method: {0}" , msg); } int count = 0; void multithread() { while ( true ) { InvokeHelper.Set( this .label1, "Text" , string .Format( "Set value: {0}" , count)); InvokeHelper.Set( this .label1, "Tag" , count); string value = InvokeHelper.Get( this .label1, "Tag" ).ToString(); InvokeHelper.Set( this .label2, "Text" , string .Format( "Get value: {0}" , value)); InvokeHelper.Invoke( this , "DoWork" , value); Thread.Sleep(500); count++; } } |
标签:
原文地址:http://www.cnblogs.com/hijushen/p/4239948.html