在CodeProject上看一個跨線程更新的方法,備忘一下。
若是在應用中存在較多簡單的跨線程操做,下面的方法可能比較實用:html
/// <summary> /// /// </summary> private static object _object = new object(); /// <summary> /// /// </summary> private static T Instance; /// <summary> /// /// </summary> /// <returns></returns> public static T GetInstance() { if (Instance == null) { lock (_object) { if (Instance == null) { Instance = new T(); } } } return Instance; }
<br>
public
static
class
ExtensionMethod
{
/// <summary>
/// 有返回值的擴展方法
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="isi"></param>
/// <param name="call"></param>
/// <returns></returns>
public
static
TResult SafeInvoke<T, TResult>(
this
T isi, Func<T, TResult> call)
where
T : ISynchronizeInvoke
{
if
(isi.InvokeRequired) {
IAsyncResult result = isi.BeginInvoke(call,
new
object
[] { isi });
object
endResult = isi.EndInvoke(result);
return
(TResult)endResult;
}
else
return
call(isi);
}
/// <summary>
/// 沒有返回值的擴展方法
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="isi"></param>
/// <param name="call"></param>
public
static
void
SafeInvoke<T>(
this
T isi, Action<T> call)
where
T : ISynchronizeInvoke
{
if
(isi.InvokeRequired) isi.BeginInvoke(call,
new
object
[] { isi });
else
call(isi);
}
|
}
|
/// <summary> /// Generic Enum.Parse implementation. /// </summary> /// <typeparam name="TEnum">The enumeration type to parse to.</typeparam> /// <param name="strEnumValue">String value to parse.</param> /// <param name="defaultValue">Default value when conversion fails.</param> /// <returns>The parsed result or the default provided when parsing failed.</returns> public static TEnum ToEnum<TEnum>(this string strEnumValue, TEnum defaultValue) { if (!Enum.IsDefined(typeof(TEnum), strEnumValue)) return defaultValue; return (TEnum)Enum.Parse(typeof(TEnum), strEnumValue); } /// <summary> /// Invoke passed in action synchronously on the GUI thread of this item. /// </summary> /// <param name="me">The control.</param> /// <param name="action">Action that will be performed on the GUI thread.</param> public static void InvokeOnGui(this Control me, Action action) { if (me.InvokeRequired) me.Invoke(action); else action(); } /// <summary> /// Invoke passed in action asynchronously on the GUI thread of this item. Note: If this method is called /// on the GUI thread, the action will be performed synchronously. If it is called from another thread, it /// is invoked asynchronoulsly. /// </summary> /// <param name="me">The control.</param> /// <param name="action">Action that will be performed on the GUI thread.</param> public static void BeginInvokeOnGui(this Control me, Action action) { if (me.InvokeRequired) me.BeginInvoke(action); else action(); }
而後在使用時就能夠使用匿名委託很方便的操做:異步
1
2
3
|
lblProcent.SafeInvoke(d => d.Text = textForLabel);
progressBar1.SafeInvoke(d => d.Value = i);
string
labelText = lblProcent.SafeInvoke(d => d.Text);
|
靜態的擴展類方法使用泛型模板擴展像全部可繼承 ISynchronizeInvoke 接口的控件,幾乎適用於常見的全部控件呦 (來自 CodeProject 爲全部類型的更新建立異步委託)async