multithreading - Thread switching -
multithreading - Thread switching -
how execute callback method in same thread calls asynchronous function. caller thread may not ui thread... ui should not hang..
thanks & regards, dinesh
there no magic bullet allow 1 thread initiate execution of delegate onto thread. target thread must specially constructed allow this. in case of ui thread there message pump dispatches , processes messages. message pump can used perform marshaling operation via isynchronizeinvoke interface.
isynchronizeinvoke target = someform; // someform form or command target.invoke( (action)(() => { messagebox.show("i on target thread"); }), null); in case thread calling asynchronous function must have kind of producer-consumer mechanism built callback execute asynchronously on thread after has been instructed worker thread. unfortunately, not trivial problem solve.
here 1 way can create thread can take delegates executed.
public class synchronizeinvokethread : isynchronizeinvoke { private thread m_thread; private blockingcollection<workitem> m_collection = new blockingcollection<workitem>(); public synchronizeinvokethread() { m_thread = new thread( () => { synchronizationcontext.setsynchronizationcontext(new mysynchronizationcontext(this)); while (true) { workitem wi = m_collection.take(); wi.complete(wi.method.dynamicinvoke(wi.args)); } }); m_thread.start(); } public iasyncresult begininvoke(delegate method, object[] args) { var wi = new workitem(method, args); m_collection.add(wi); homecoming wi; } public object endinvoke(iasyncresult result) { var wi = (workitem)result; wi.asyncwaithandle.waitone(); homecoming wi.result; } public object invoke(delegate method, object[] args) { var wi = new workitem(method, args); m_collection.add(wi); wi.asyncwaithandle.waitone(); homecoming wi.result; } public bool invokerequired { { homecoming thread.currentthread != m_thread; } } private class mysynchronizationcontext : synchronizationcontext { private isynchronizeinvoke m_synchronizingobject; public mysynchronizationcontext(isynchronizeinvoke synchronizingobject) { m_synchronizingobject = synchronizingobject; } public override void post(sendorpostcallback d, object state) { m_synchronizingobject.begininvoke(d, new object[] { state }); } public override void send(sendorpostcallback d, object state) { m_synchronizingobject.invoke(d, new object[] { state }); } } private class workitem : iasyncresult { private delegate m_method; private object[] m_args; private object m_result = null; private manualresetevent m_signal = new manualresetevent(false); public workitem(delegate method, object[] args) { m_method = method; m_args = args; } public void complete(object result) { m_result = result; m_signal.set(); } public object result { { homecoming m_result; } } public delegate method { { homecoming m_method; } } public object[] args { { homecoming m_args; } } public object asyncstate { { homecoming null; } } public waithandle asyncwaithandle { { homecoming m_signal; } } public bool completedsynchronously { { homecoming false; } } public bool iscompleted { { homecoming m_signal.waitone(0); } } } } it can used this.
isynchronizeinvoke target = new synchronizeinvokethread(); target.invoke( (action)(() => { console.writeline("i on target thread"); synchronizationcontext.current.post( (state) => { console.writeline("i have synchronization context!"); }, null); }), null); update:
per comment below blockingcollection available in .net 4.0 or part of reactive extensions download. if info construction not available hard code became harder.
multithreading c#-2.0
Comments
Post a Comment