您的位置:首页 > 其它

跨线程时使用静态扩展方法更新控件

2015-11-05 10:06 363 查看
在CodeProject上看一个跨线程更新的方法,备忘一下。
如果在应用中存在较多简单的跨线程操作,下面的方法可能比较实用:

/// <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;

}


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();
}


然后在使用时就可以使用匿名委托很方便的操作:

lblProcent.SafeInvoke(d => d.Text = textForLabel);
progressBar1.SafeInvoke(d => d.Value = i);
string labelText = lblProcent.SafeInvoke(d => d.Text);


静态的扩展类方法使用泛型模板扩展像所有可继承 ISynchronizeInvoke 接口的控件,几乎适用于常见的所有控件呦 (来自 CodeProject 为所有类型的更新创建异步委托
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: