You don't have to send anything from one thread to another.
Both threads can read variables updated by the other thread (periodically or not) and perform actions accordingly.
As simple as that!
Of course you can choose any way to implement the alleged passing of data, one way is using a Queue.
e.g.:
public class Queue<T>
{
private readonly Locker _Locker = new Locker();
private readonly System.Collections.Generic.Queue<T> _Queue = new System.Collections.Generic.Queue<T>();
public void Enqueue(T item)
{
lock (_Locker)
{
_Queue.Enqueue(item);
}
}
public virtual void EnqueueRange(IEnumerable<T> items)
{
lock (_Locker)
{
if (items == null)
{
return;
}
foreach (T item in items)
{
_Queue.Enqueue(item);
}
}
}
public T Dequeue()
{
lock (_Locker)
{
return _Queue.Dequeue();
}
}
public void Clear()
{
lock (_Locker)
{
_Queue.Clear();
}
}
public Int32 Count
{
get
{
lock (_Locker)
{
return _Queue.Count;
}
}
}
public Boolean TryDequeue(out T item)
{
lock (_Locker)
{
if (_Queue.Count > 0)
{
item = _Queue.Dequeue();
return true;
}
else
{
item = default(T);
return false;
}
}
}
}