Hi guys.
Im having a problem with this.
I have an object that i create in other thread. Now what i want to do, is that when i close my app in the event it must call a method from the object created in the thread maded earlier.
How can i do this? I ve tried calling just the object by its name but it doesnt work.
Thanks
krosty4782 0 Light Poster
Dani AI
Generated
created the worker object inside the worker thread (the run() method), which is why socketConectado.METHOD() from the closing event appears to “not work”: the main thread may see a null reference or the call may need to run on the worker thread itself. Two distinct approaches cover the usual needs.
First, if the main thread simply needs a safe reference to call thread-safe methods on the object, publish the reference safely and signal when it’s ready. For example, create a shared field, publish it with Interlocked.Exchange (or under a lock/Volatile.Write) and use a ManualResetEventSlim to wait briefly in the close handler before calling the cleanup method. Make the cleanup method itself thread-safe so it can be called from the closing thread without race conditions.
private ConectadoThread socketConectado;
private ManualResetEventSlim created = new ManualResetEventSlim();
// worker thread: create and publish
var local = new ConectadoThread();
Interlocked.Exchange(ref socketConectado, local);
created.Set();
local.RunLoop();
// closing: wait then call a thread-safe stop/close
if (created.Wait(2000)) {
var sc = Interlocked.Exchange(ref socketConectado, null);
sc?.RequestStop(); // RequestStop signals the worker to shutdown safely
} Second, if the method must execute on the worker thread (not just be invoked from another thread), change the worker to accept commands: a ConcurrentQueue<Action> plus an AutoResetEvent (or BlockingCollection<T>). Expose a Post(Action) or EnqueueCommand(...) method that enqueues the delegate and signals the worker; the worker loop dequeues and runs commands on its own thread. This pattern avoids cross-thread invocation and deadlocks.
Also note points from earlier replies: ’s idea of passing parameters into threads is valid (pass objects or create them before starting the thread), and ’s warning about UI marshalling stands—use Control.Invoke/Dispatcher.Invoke (or SynchronizationContext) only when the method touches UI components. Avoid blocking the UI on shutdown; prefer signalling with timeouts and graceful shutdown; in modern code prefer Task + CancellationToken for cleaner cancellation semantics.
Recommended Answers
Jump to Post— kvprajapati 1,826Please show us your code work. You should have to use Parameterized Thread.
All 3 Replies
kvprajapati 1,826 Posting Genius Team Colleague
Please show us your code work. You should have to use Parameterized Thread.
sknake 1,622 Senior Poster Featured Poster
If you are trying to marshal a call to the GUI thread it depends -- Is it a windows form or WPF application? Winforms use Control.Invoke() while WPF uses Dispather.Invoke() .
Here is a recent thread with a similar question, using winforms:
http://www.daniweb.com/forums/thread318221.html
If you're wanting to marshal the call a non-GUI thread you need to implement ISynchronizeInvoke . IDesign has an example of an ISynchronizeInvoke implementation:
Taken from idesign:
// © 2005 IDesign Inc. All rights reserved
//Questions? Comments? go to
//http://www.idesign.net
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading;
using System.Security.Permissions;
[Serializable]
internal class WorkItem : IAsyncResult
{
object[] m_Args;
object m_AsyncState;
bool m_Completed;
Delegate m_Method;
ManualResetEvent m_Event;
object m_MethodReturnedValue;
internal WorkItem(object AsyncState,Delegate method,object[] args)
{
m_AsyncState = AsyncState;
m_Method = method;
m_Args = args;
m_Event = new ManualResetEvent(false);
m_Completed = false;
}
//IAsyncResult properties
object IAsyncResult.AsyncState
{
get
{
return m_AsyncState;
}
}
WaitHandle IAsyncResult.AsyncWaitHandle
{
get
{
return m_Event;
}
}
bool IAsyncResult.CompletedSynchronously
{
get
{
return false;
}
}
bool IAsyncResult.IsCompleted
{
get
{
return Completed;
}
}
bool Completed
{
get
{
lock(this)
{
return m_Completed;
}
}
set
{
lock(this)
{
m_Completed = value;
}
}
}
//This method is called on the worker thread to execute the method
internal void CallBack()
{
MethodReturnedValue = m_Method.DynamicInvoke(m_Args);
//Method is done. Signal the world
m_Event.Set();
Completed = true;
}
internal object MethodReturnedValue
{
get
{
lock(this)
{
return m_MethodReturnedValue;
}
}
set
{
lock(this)
{
m_MethodReturnedValue = value;
}
}
}
}
[SecurityPermission(SecurityAction.Demand,ControlThread = true)]
public class Synchronizer: ISynchronizeInvoke,IDisposable
{
WorkerThread m_WorkerThread;
public bool InvokeRequired
{
get
{
bool res = Thread.CurrentThread.ManagedThreadId == m_WorkerThread.ManagedThreadId;
return ! res;
}
}
public IAsyncResult BeginInvoke(Delegate method, object[] args)
{
WorkItem result = new WorkItem(null,method,args);
m_WorkerThread.QueueWorkItem(result);
return result;
}
public object EndInvoke(IAsyncResult result)
{
result.AsyncWaitHandle.WaitOne();
WorkItem workItem = (WorkItem)result;
return workItem.MethodReturnedValue;
}
public object Invoke(Delegate method, object[] args)
{
IAsyncResult asyncResult;
asyncResult = BeginInvoke(method,args);
return EndInvoke(asyncResult);
}
public Synchronizer()
{
m_WorkerThread = new WorkerThread(this);
}
~Synchronizer()
{
}
public void Dispose()
{
m_WorkerThread.Kill();
}
internal protected class WorkerThread
{
public Thread m_ThreadObj;
bool m_EndLoop;
Mutex m_EndLoopMutex;
AutoResetEvent m_ItemAdded;
Synchronizer m_Synchronizer;
Queue<WorkItem> m_WorkItemQueue;
public int ManagedThreadId
{
get
{
return m_ThreadObj.ManagedThreadId;
}
}
internal void QueueWorkItem(WorkItem workItem)
{
lock(m_WorkItemQueue)
{
m_WorkItemQueue.Enqueue(workItem);
m_ItemAdded.Set();
}
}
internal WorkerThread(Synchronizer synchronizer)
{
m_Synchronizer = synchronizer;
m_EndLoop = false;
m_ThreadObj = null;
m_EndLoopMutex = new Mutex();
m_ItemAdded = new AutoResetEvent(false);
m_WorkItemQueue = new Queue<WorkItem>();
CreateThread(true);
}
bool EndLoop
{
set
{
m_EndLoopMutex.WaitOne();
m_EndLoop = value;
m_EndLoopMutex.ReleaseMutex();
}
get
{
bool result = false;
m_EndLoopMutex.WaitOne();
result = m_EndLoop;
m_EndLoopMutex.ReleaseMutex();
return result;
}
}
Thread CreateThread(bool autoStart)
{
if(m_ThreadObj != null)
{
Debug.Assert(false);
return m_ThreadObj;
}
m_ThreadObj = new Thread(Run);
m_ThreadObj.Name = "Synchronizer Worker Thread";
if(autoStart == true)
{
m_ThreadObj.Start();
}
return m_ThreadObj;
}
void Start()
{
Debug.Assert(m_ThreadObj != null);
Debug.Assert(m_ThreadObj.IsAlive == false);
m_ThreadObj.Start();
}
bool QueueEmpty
{
get
{
lock(m_WorkItemQueue)
{
if(m_WorkItemQueue.Count > 0)
{
return false;
}
return true;
}
}
}
WorkItem GetNext()
{
if(QueueEmpty)
{
return null;
}
lock(m_WorkItemQueue)
{
return m_WorkItemQueue.Dequeue();
}
}
void Run()
{
while(EndLoop == false)
{
while(QueueEmpty == false)
{
if(EndLoop == true)
{
return;
}
WorkItem workItem = GetNext();
workItem.CallBack();
}
m_ItemAdded.WaitOne();
}
}
public void Kill()
{
//Kill is called on client thread - must use cached thread object
Debug.Assert(m_ThreadObj != null);
if(m_ThreadObj.IsAlive == false)
{
return;
}
EndLoop = true;
m_ItemAdded.Set();
//Wait for thread to die
m_ThreadObj.Join();
if(m_EndLoopMutex != null)
{
m_EndLoopMutex.Close();
}
if(m_ItemAdded != null)
{
m_ItemAdded.Close();
}
}
}
} Edited by sknake because: clarity
kvprajapati commented: Awesome! +11
krosty4782 0 Light Poster
I will post my code, so you can tell me if i have to use isynchronizeinvoke or what.
In Form1:
thread = new Thread(run);
thread.Start();
public void run()
{
socketConectado = new ConectadoThread();
} Now, i want to call a method of "socketConectado".
How can i do this?
I cant just put socketConectado.METHOD()
Thanks
Be a part of the DaniWeb community
We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.