public static TResult SafeInvoke<t,>(this T isi, Func<t,> 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);
}
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);
}
Usage:
lblProcent.SafeInvoke(d => d.Text = "Written by the background thread");
progressBar1.SafeInvoke(d => d.Value = i);
//or call a methode thread safe. That method is executed on the same thread as the form
this.SafeInvoke(d => d.UpdateFormItems("test1", "test2"));
// A threadSafe getter is also available. The getter knows what the return type is, so casting is not necessary.
string textboxtext=textbox.SafeInvoke(d=>d.textbox.text);
Another way, like Event broke
Synchronizing calls to the UI in a multi threaded application
public class MessageBroker
{
private readonly Dictionary<Type, object> consumers;
private readonly SynchronizationContext synchronizationContext;
public MessageBroker()
{
consumers = new Dictionary<Type, object>();
synchronizationContext = AsyncOperationManager.SynchronizationContext;
}
public void Send<T>(T message)
{
var key = typeof(T);
if (!consumers.ContainsKey(key)) return;
var list = consumers[key] as List<Action<T>>;
list.ForEach(action =>
synchronizationContext.Post(m => action((T)m), message));
}
public void Register<T>(Action<T> action)
{
var key = typeof (T);
List<Action<T>> list;
if (!consumers.ContainsKey(key))
{
list = new List<Action<T>>();
consumers.Add(key, list);
}
else
list = consumers[key] as List<Action<T>>;
list.Add(action);
}
}
Message Buspublic static class MessageBus
{
private static MessageBroker messageBroker;
private static MessageBroker Broker
{
get
{
if (messageBroker == null)
messageBroker = new MessageBroker();
return messageBroker;
}
}
public static void Send<T>(T message)
{
Broker.Send(message);
}
public static void Register<T>(Action<T> action)
{
Broker.Register(action);
}
}
最後一種方式跟以上的方向剛好相反,在UI上用個Timer,定時取得來源資料,並更新到表單上,就不用考慮執行緒更新的問題了… Written with StackEdit.
沒有留言:
張貼留言