Delegates dispatched by dispatcher are never fired - c#

I am trying to fire a method as a result to an asynchronous read operation on a NetworkStream. The read operation is done via BeginRead and EndRead, resulting in the EndRead being called in the callback specified with BeginRead. All pretty basic stuff. Now, as the callback is done in a system generated Thread, the data read from the NetworkStream is no longer owned by my thread, that called the BeginRead. To overcome that, I wrote a method to further process the data read, which I try to call via my Thread's dispatcher.
// These are created in my Thread
private delegate void ReceiverCallback(IPEndPoint sender, byte[] data);
private Dispatcher dispatcher = Dispatcher.CurrentDispatcher;
With the callback looking like this:
private void DataReceived(IAsyncResult result)
{
DataReceivedStruct drs = (DataReceivedStruct)result.AsyncState;
NetworkStream used = drs.stream;
AutoResetEvent handle = drs.waitHandle;
used.EndRead(result);
DispatchRaiseReceived(readBuffer);
handle.Set();
}
The DataReceivedStruct is a simple struct holding the NetworkStream and an AutoResetEvent.
ReadBuffer is a global private byte[] of 1024 length, as BeginRead and EndRead aren't called in the same method.
The DispatchRaiseReceive method looks like this:
private void DispatchRaiseReceived(byte[] data)
{
dispatcher.BeginInvoke((ReceiverCallback)RaiseReceived, socket.Client.RemoteEndPoint, data);
}
Where socket is a TcpClient object.
The disptached method looks like the following bit of code. What this does is simply pass the data along via an event for further processing.
private void RaiseReceived(IPEndPoint sender, byte[] data)
{
if(IsEnabled){
if (Received != null)
{
Received(this, new TCPDataArgs(sender, data));
}
}
}
The actual method that the dispatcher needs to call, is never called. Now from what I've been able to find on the web is that it could have something to do with the dispatcher not being created on the correct Thread, and thus it is never invoking the method on the correct Thread. However, the dispatcher is created on my Thread, so that shouldn't apply.

As an attempt to fix this, I explicitly got the Dispatcher from my UI-Thread, and passed that along to the desired place I wanted to use it. This instead of trying to get it with Dispatcher.CurrentDispatcher. And what do you know, it worked. The delegate is now being called correctly.
Apparently Dispatcher.CurrentDispatcher didn't get the correct Dispatcher I wanted it to use.

Related

Changing SynchronizationContext Within Async Method

I am trying to post a lean question here, without code, because my question is so specific: Is it possible/acceptable to modify the SynchronizationContext within an Async method? If I don't set SynchronizationContext when the Async method begins, it seems that code within it--including events I raise and methods within the same class module I call--run on the same worker thread. However, when it comes time to interact with the UI, I find that the SynchronizationContext has to be set to the UI thread.
Is it okay to keep the SynchronizationContext set to the worker thread until such time that I want to invoke a call to a UI-based function?
EDIT:
To further clarify my above question, I find myself in a no-win situation with respect to the SynchronizationContext setting. If don't set the SynchronizationContext then my async operations run on a separate thread (as desired) but then I can't return data to the UI thread without encountering a cross-thread operation exception; if I set the SynchronizationContext to my UI thread then the operations I want to run on a separate thread end up running on the UI thread--and then (of course) I avoid the cross-thread exception and everything works. Clearly, I'm missing something.
If you care to read more, I've tried to provide a very clear explanation of what I'm trying to do and I realize you're investing your time to understand so thank you for that!
What I'm trying to do is shown in this flow diagram:
I have a Winforms application running on the UI thread (in black); I have a Socket object I'd like to run on its own thread. The job of the socket class is to read data from a communication socket and raise events back to the UI whenever data arrives.
Note that I start a message loop from the UI thread so that the socket is continually polled for data on its own thread; if data is received, I want to process that data synchronously on the same non-UI thread before grabbing any more data from the socket. (Yes, if something goes awry with any particular socket read, the socket might be left with unread data in it.)
The code to start the message loop looks like this:
if (Socket.IsConnected)
{
SetUpEventListeners();
// IMPORTANT: next line seems to be required in order to avoid a cross-thread error
SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext());
Socket.StartMessageLoopAsync();
}
When I start the message loop from the UI thread, I call an async method on the Socket object:
public async void StartMessageLoopAsync()
{
while (true)
{
// read socket data asynchronously and populate the global DataBuffer
await ReadDataAsync();
if (DataBuffer.Count == 0)
{
OnDataReceived();
}
}
}
The Socket object also has the OnDataReceived() method defined as:
protected void OnDataReceived()
{
var dataEventArgs = new DataEventArgs();
dataEventArgs.DataBuffer = DataBuffer;
// *** cross-thread risk here!
DataReceived?.Invoke(this, dataEventArgs);
}
I have highlighted two areas of the diagram with "1" and "2" blue stars.
In "1" (on the diagram), I am using the async/await pattern. I am using a third-party socket tool that doesn't support Async, so I have wrapped that in my own ReadDataAsync() function that looks like this:
public override async Task ReadDataAsync()
{
// read a data asynchronously
var task = Task.Run(() => ReadData());
await task;
}
ReadData() wraps the third-party component's read method: it populates a global data buffer, so no return value is needed.
In "2" in the diagram, I am encountering the cross-thread risk described in my OnDataReceived() method cited above.
Bottom Line: If I set SynchronizationContext as shown in my first code clip above, then everything in the Socket object runs on its own thread until I try to invoke the DataReceived event handler; if I comment-out the SynchronizationContext then the only part of the code that runs on its own thread is the brief third-party socket-read operation wrapped in my DataReadAsync() method.
So my thought was whether I can set the SynchronizationContext just ahead of trying to invoke the DataReceived event handler. And even if I "can", the better question is whether this is a good idea. If I do modify SynchronizationContext within the non-UI thread then I'd have to set it back to its original value after invoking the DataReceived method, and that has a Durian-like code-smell to me.
Is there an elegant tweak to my design or does it need an overhaul? My goal is to have all red items in the diagram running on a non-UI thread and the black items running on the UI thread. "2" is the point at which the non-UI thread my cross over to the UI thread...
Thank you.
Setting context directly isn't the best idea since other functionality being occasionally executed in this thread can be affected. The most natural way to control synchronization context for async/await flows is using ConfigureAwait. So in your case I see two options to achieve what you want:
1) Use ConfigureAwait(false) with ReadDataAsync
public async void StartMessageLoopAsync()
{
while (true)
{
// read socket data asynchronously and populate the global DataBuffer
await ReadDataAsync().ConfigureAwait(false);
if (DataBuffer.Count == 0)
{
OnDataReceived();
}
}
}
which will make resuming everything after await in background thread. And then use Dispatcher Invoke to marshal DataReceived?.Invoke into UI thread:
protected void OnDataReceived()
{
var dataEventArgs = new DataEventArgs();
dataEventArgs.DataBuffer = DataBuffer;
// *** cross-thread risk here!
Dispatcher.CurrentDispathcer.Invoke(() => { DataReceived?.Invoke(this, dataEventArgs ); });
}
Or 2) Make some logic decomposition like as follows:
public async void StartMessageLoopAsync()
{
while (true)
{
// read socket data asynchronously and populate the global DataBuffer
await ProcessDataAsync();
// this is going to run in UI thread but there is only DataReceived invocation
if (DataBuffer.Count == 0)
{
OnDataReceived();
}
}
}
OnDataReceived is thin now and does only event triggering
protected void OnDataReceived()
{
// *** cross-thread risk here!
DataReceived?.Invoke(this, dataEventArgs);
}
This consolidates the functionality supposed to run in background thread
private async Task ProcessDataAsync()
{
await ReadDataAsync().ConfigureAwait(false);
// this is going to run in background thread
var dataEventArgs = new DataEventArgs();
dataEventArgs.DataBuffer = DataBuffer;
}
public override async Task ReadDataAsync()
{
// read a data asynchronously
var task = Task.Run(() => ReadData());
await task;
}
This seems like a scenario better served with reactive extensions:
Reactive Extensions for .NET

Callback method indirectly calling back itself

In a C# class, the following format is used for reading data from a socket asynchronously.
As you can see in the code, it uses AsyncReceive to read data from a socket. It calls back OnDataReception when data is received.
In OnDataReception, received data is processed and again calls ListenForData if the conversation is not finished yet.
Does this code snippet create any kind of indefinite recursion? (functions or threads)
class ClientConnection{
Socket socket = ...
SocketAsyncEventArgs args = ...
args.Completed += new EventHandler<SocketAsyncEventArgs>(OnDataReception);
...
public void ListenForData(){
...
socket.ReceiveAsync(args);
...
}
public void OnDataReception(Object obj, SocketAsyncEventArgs args){
...
// if conversation is finished, return
// else call ListenForData() again...
}
...
}
First I like to mention, that the question is similar to How does this not cause a stack overflow?.
Now to be specific on your questions: The amount of threads used by the code snippet is constrained by the number of threads available in the thread pool used to execute ReceiveAsync. New threads are just produced, if a previous call to the async method returned.
Further OnDataReception does call ListenForData every time. ListenForData instead does not directly call OnDataReception. This means, there is no direct functional recursion between the two methods. ReceiveAsync executed in a background-thread does not produce nested stack-frames.
So in my opinion there are no hidden recursions in the code.
Per MSDN Documentation on Socket.ReceiveAsync:
Returns true if the I/O operation is pending. The
SocketAsyncEventArgs.Completed event on the e parameter will be raised
upon completion of the operation.
Returns false if the I/O operation
completed synchronously. In this case, The
SocketAsyncEventArgs.Completed event on the e parameter will not be
raised and the e object passed as a parameter may be examined
immediately after the method call returns to retrieve the result of
the operation.
To answer your question, no it will not create an infinite loop/recursion.
Your ListenForData method will only call OnDataReception once per call to ReceiveAsync. Since you are calling ListenForData in OnDataReception and not in a loop, it will look like this:
ListenForData called!
(time elapses)
OnDataReception called!
ListenForData called!
(time elapses)
OnDataReception called!
ListenForData called!
...
This is almost identical to using Socket.BeginReceive, passing an AsyncCallback and then calling Socket.EndReceive followed by another Socket.BeginReceive in the callback. It's an indefinite loop but not an infinite one.
See:
void StartReceiving()
{
// Start receiving asynchronously...
socket.BeginReceive(recvBuffer, 0, recvBuffer.Length, SocketFlags.None, OnDataReceived, null);
}
void OnDataReceived(IAsyncResult result)
{
// Finish receiving this data.
var numberOfBytesReceived = socket.EndReceive(result);
// Start receiving asynchronously again...
if(numberOfBytesReceived > 0 && socket.Connected)
socket.BeginReceive(recvBuffer, 0, recvBuffer.Length, SocketFlags.None, OnDataReceived, null);
}
This would not produce any indefinite recursion, but you can change the architecture slightly for the effective resource utilization.
You could use two different threads for listening and the conversion, since the program need to listen the port irrespective of the conversion result.

C# Firing events within the thread they are added

Consider two classes; Producer and Consumer (the same as classical pattern, each with their own threads). Is it possible for Producer to have an Event which Consumer can register to and when the producer triggers the event, the consumer's event handler is run in its own thread? Here are my assumptions:
Consumer does not know if the Producer's event is triggered
within his own thread or another.
Neither Producer nor Consumer are descendants of Control so they don't have
BeginInvoke method inherited.
PS. I'm not trying to implement Producer - Consumer pattern. These are two simple classes which I'm trying to refactor the producer so it incorporates threads.
[UPDATE]
To further expand my problem, I'm trying to wrap a hardware driver to be worked with in the simplest way possible. For instance my wrapper will have a StateChanged event which the main application will register to so it will be notified when hardware is disconnected. As the actual driver has no means other than polling to check its presence , I will need to start a thread to check it periodically. Once it is not available anymore I will trigger the event which needs to be executed in the same thread as it was added. I know this is a classical Producer-Consumer pattern but since I'm trying to simplify using my driver-wrapper, I don't want the user code to implement consumer.
[UPDATE]
Due to some comments suggesting that there's no solution to this problem, I would like to add few lines which might change their minds. Considering the BeginInvoke can do what I want, so it shouldn't be impossible (at least in theory). Implementing my own BeginInvoke and calling it within the Producer is one way to look at it. It's just that I don't know how BeginInvoke does it!
You want to do inter thread communication. Yes it is possible.
Use System.Windows.Threading.Dispatcher
http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.aspx
The Dispatcher maintains a prioritized queue of work items for a specific thread.
When a Dispatcher is created on a thread, it becomes the only Dispatcher that can be associated with the thread, even if the Dispatcher is shut down.
If you attempt to get the CurrentDispatcher for the current thread and a Dispatcher is not associated with the thread, a Dispatcher will be created. A Dispatcher is also created when you create a DispatcherObject. If you create a Dispatcher on a background thread, be sure to shut down the dispatcher before exiting the thread.
Yes there is a way to do this. It relies on using the SynchronizationContext class (docs). The sync context abstracts the operations of sending messages from one thread to another via the methods Send (synchronous for the calling thread) and Post(async for the calling thread).
Let's take a slightly simpler situation where you only want the capture one sync context, the context of the "creator" thread. You would do something like this:
using System.Threading;
class HardwareEvents
{
private SynchronizationContext context;
private Timer timer;
public HardwareEvents()
{
context = SynchronizationContext.Current ?? new SynchronizationContext();
timer = new Timer(TimerMethod, null, 0, 1000); // start immediately, 1 sec interval.
}
private void TimerMethod(object state)
{
bool hardwareStateChanged = GetHardwareState();
if (hardwareStateChanged)
context.Post(s => StateChanged(this, EventArgs.Empty), null);
}
public event EventHandler StateChanged;
private bool GetHardwareState()
{
// do something to get the state here.
return true;
}
}
Now, the creating thread's sync context will be used when events are invoked. If the creating thread was a UI thread it will have a sync context supplied by the framework. If there is no sync context, then the default implementation is used, which invokes on the thread pool. SynchronizationContext is a class that you can subclass if you want to provide a custom way to send a message from the producer to the consumer thread. Just override Post and Send to send said message.
If you wanted every event subscriber to get called back on their own thread, you would have to capture the sync context in the add method. You then hold on to pairs of sync contexts and delegates. Then when raising the event, you would loop through the sync context / delegate pairs and Post each one in turn.
There are several other ways you could improve this. For example, you may want to suspend polling the hardware if there no subscribers to the event. Or you might want to back off your polling frequency if the hardware does not respond.
First, please note that in .NET / the Base Class Library, it is usually the event subscriber's obligation to ensure that its callback code is executing on the correct thread. That makes it easy for the event producer: it may just trigger its event without having to care about any thread affinities of its various subscribers.
Here's a complete example step-by-step of a possible implementation.
Let's start with something simple: The Producer class and its event, Event. My example won't include how and when this event gets triggered:
class Producer
{
public event EventHandler Event; // raised e.g. with `Event(this, EventArgs.Empty);`
}
Next, we want to be able to subscribe our Consumer instances to this event and be called back on a specific thread (I'll call this kind of thread a "worker thread"):
class Consumer
{
public void SubscribeToEventOf(Producer producer, WorkerThread targetWorkerThread) {…}
}
How do we implement this?
First, we need the means to "send" code to a specific worker thread. Since there is no way to force a thread to execute a particular method whenever you want it to, you must arrange for a worker thread to explicitly wait for work items. One way to do this is via a work item queue. Here's a possible implementation for WorkerThread:
sealed class WorkerThread
{
public WorkerThread()
{
this.workItems = new Queue<Action>();
this.workItemAvailable = new AutoResetEvent(initialState: false);
new Thread(ProcessWorkItems) { IsBackground = true }.Start();
}
readonly Queue<Action> workItems;
readonly AutoResetEvent workItemAvailable;
public void QueueWorkItem(Action workItem)
{
lock (workItems) // this is not extensively tested btw.
{
workItems.Enqueue(workItem);
}
workItemAvailable.Set();
}
void ProcessWorkItems()
{
for (;;)
{
workItemAvailable.WaitOne();
Action workItem;
lock (workItems) // dito, not extensively tested.
{
workItem = workItems.Dequeue();
if (workItems.Count > 0) workItemAvailable.Set();
}
workItem.Invoke();
}
}
}
This class basically starts a thread, and puts it in an infinite loop that falls asleep (WaitOne) until an item arrives in its queue (workItems). Once that happens, the item — an Action — is dequeued and invoked. Then the thread goes to sleep again (WaitOne)) until another item is available in the queue.
Actions are put in the queue via the QueueWorkItem method. So essentially we can now send code to be executed to a specific WorkerThread instance by calling that method. We're now ready to implement Customer.SubscribeToEventOf:
class Consumer
{
public void SubscribeToEventOf(Producer producer, WorkerThread targetWorkerThread)
{
producer.Event += delegate(object sender, EventArgs e)
{
targetWorkerThread.QueueWorkItem(() => OnEvent(sender, e));
};
}
protected virtual void OnEvent(object sender, EventArgs e)
{
// this code is executed on the worker thread(s) passed to `Subscribe…`.
}
}
Voilà!
P.S. (not discussed in detail): As an add-on, you could package the method of sending code to WorkerThread using a standard .NET mechanism called a SynchronizationContext:
sealed class WorkerThreadSynchronizationContext : SynchronizationContext
{
public WorkerThreadSynchronizationContext(WorkerThread workerThread)
{
this.workerThread = workerThread;
}
private readonly WorkerThread workerThread;
public override void Post(SendOrPostCallback d, object state)
{
workerThread.QueueWorkItem(() => d(state));
}
// other overrides for `Send` etc. omitted
}
And at the beginning of WorkerThread.ProcessWorkItems, you'd set the synchronization context for that particular thread as follows:
SynchronizationContext.SetSynchronizationContext(
new WorkerThreadSynchronizationContext(this));
I posted earlier that I've been there, and that there is no nice solution.
However, I just stumbled upon something I have done in another context before: you could instantiate a timer (that is, Windows.Forms.Timer) when you create your wrapper object. This timer will post all Tick events to the ui thread.
Now if you're device polling logic is non-blocking and fast, you could implement it directly inside the timer Tick event, and raise your custom event there.
Otherwise, you could continue to do the polling logic inside a thread, and instead of firing the event inside the thread, you just flip some boolean variable which gets read by the timer every 10 ms, who then fires the event.
Note that this solution still requires that the object is created from the GUI thread, but at least the user of the object will not have to worry about Invoke.
It is possible. One typical approach is to use the BlockingCollection class. This data structure works like a normal queue except that the dequeue operation blocks the calling thread if the queue is empty. The produce will queue items by calling Add and the consumer will dequeue them by calling Take. The consumer typically runs it's own dedicated thread spinning an infinite loop waiting for items to appear in the queue. This is, more or less, how the message loop on the UI thread operates and is the basis for getting the Invoke and BeginInvoke operations to accomplish the marshaling behavior.
public class Consumer
{
private BlockingCollection<Action> queue = new BlockingCollection<Action>();
public Consumer()
{
var thread = new Thread(
() =>
{
while (true)
{
Action method = queue.Take();
method();
}
});
thread.Start();
}
public void BeginInvoke(Action method)
{
queue.Add(item);
}
}

How can I safely raise events in an AsyncCallback?

I'm writing a wrapper class around a TcpClient which raises an event when data arrives. I'm using BeginRead and EndRead, but when the parent form handles the event, it's not running on the UI thread. I do I need to use delegates and pass the context into the callback? I thought that callbacks were a way to avoid this...
void ReadCallback(IAsyncResult ar)
{
int length = _tcpClient.GetStream().EndRead(ar);
_stringBuilder.Append(ByteArrayToString(_buffer, length));
BeginRead();
OnStringArrival(EventArgs.Empty);
}
The parent form should be using the Invoke method on its controls in the event handler to ensure it's on the right thread; it's not the job of your background process to conform to what the UI needs. This msdn page has an example.

Is it possible to put an event handler on a different thread to the caller?

Lets say I have a component called Tasking (that I cannot modify) which exposes a method “DoTask” that does some possibly lengthy calculations and returns the result in via an event TaskCompleted. Normally this is called in a windows form that the user closes after she gets the results.
In my particular scenario I need to associate some data (a database record) with the data returned in TaskCompleted and use that to update the database record.
I’ve investigated the use of AutoResetEvent to notify when the event is handled. The problem with that is AutoResetEvent.WaitOne() will block and the event handler will never get called. Normally AutoResetEvents is called be a separate thread, so I guess that means that the event handler is on the same thread as the method that calls.
Essentially I want to turn an asynchronous call, where the results are returned via an event, into a synchronous call (ie call DoSyncTask from another class) by blocking until the event is handled and the results placed in a location accessible to both the event handler and the method that called the method that started the async call.
public class SyncTask
{
TaskCompletedEventArgs data;
AutoResetEvent taskDone;
public SyncTask()
{
taskDone = new AutoResetEvent(false);
}
public string DoSyncTask(int latitude, int longitude)
{
Task t = new Task();
t.Completed = new TaskCompletedEventHandler(TaskCompleted);
t.DoTask(latitude, longitude);
taskDone.WaitOne(); // but something more like Application.DoEvents(); in WinForms.
taskDone.Reset();
return data.Street;
}
private void TaskCompleted(object sender, TaskCompletedEventArgs e)
{
data = e;
taskDone.Set(); //or some other mechanism to signal to DoSyncTask that the work is complete.
}
}
In a Windows App the following works correctly.
public class SyncTask
{
TaskCompletedEventArgs data;
public SyncTask()
{
taskDone = new AutoResetEvent(false);
}
public string DoSyncTask(int latitude, int longitude)
{
Task t = new Task();
t.Completed = new TaskCompletedEventHandler(TaskCompleted);
t.DoTask(latitude, longitude);
while (data == null) Application.DoEvents();
return data.Street;
}
private void TaskCompleted(object sender, TaskCompletedEventArgs e)
{
data = e;
}
}
I just need to replicate that behaviour in a window service, where Application.Run isn’t called and the ApplicationContext object isn’t available.
I've had some trouble lately with making asynchronous calls and events at threads and returning them to the main thread.
I used SynchronizationContext to keep track of things. The (pseudo)code below shows what is working for me at the moment.
SynchronizationContext context;
void start()
{
//First store the current context
//to call back to it later
context = SynchronizationContext.Current;
//Start a thread and make it call
//the async method, for example:
Proxy.BeginCodeLookup(aVariable,
new AsyncCallback(LookupResult),
AsyncState);
//Now continue with what you were doing
//and let the lookup finish
}
void LookupResult(IAsyncResult result)
{
//when the async function is finished
//this method is called. It's on
//the same thread as the the caller,
//BeginCodeLookup in this case.
result.AsyncWaitHandle.WaitOne();
var LookupResult= Proxy.EndCodeLookup(result);
//The SynchronizationContext.Send method
//performs a callback to the thread of the
//context, in this case the main thread
context.Send(new SendOrPostCallback(OnLookupCompleted),
result.AsyncState);
}
void OnLookupCompleted(object state)
{
//now this code will be executed on the
//main thread.
}
I hope this helps, as it fixed the problem for me.
Maybe you could get DoSyncTask to start a timer object that checks for the value of your data variable at some appropriate interval. Once data has a value, you could then have another event fire to tell you that data now has a value (and shut the timer off of course).
Pretty ugly hack, but it could work... in theory.
Sorry, that's the best I can come up with half asleep. Time for bed...
I worked out a solution to the async to sync problem, at least using all .NET classes.
Link
It still doesn't work with COM. I suspect because of STA threading. The Event raised by the .NET component that hosts the COM OCX is never handled by my worker thread, so I get a deadlock on WaitOne().
someone else may appreciate the solution though :)
If Task is a WinForms component, it might be very aware of threading issues and Invoke the event handler on the main thread -- which seems to be what you're seeing.
So, it might be that it relies on a message pump happening or something. Application.Run has overloads that are for non-GUI apps. You might consider getting a thread to startup and pump to see if that fixes the issue.
I'd also recommend using Reflector to get a look at the source code of the component to figure out what it's doing.
You've almost got it. You need the DoTask method to run on a different thread so the WaitOne call won't prevent work from being done. Something like this:
Action<int, int> doTaskAction = t.DoTask;
doTaskAction.BeginInvoke(latitude, longitude, cb => doTaskAction.EndInvoke(cb), null);
taskDone.WaitOne();
My comment on Scott W's answer seems a little cryptic after I re-read it. So let me be more explicit:
while( !done )
{
taskDone.WaitOne( 200 );
Application.DoEvents();
}
The WaitOne( 200 ) will cause it to return control to your UI thread 5 times per second (you can adjust this as you wish). The DoEvents() call will flush the windows event queue (the one that handles all windows event handling like painting, etc.). Add two members to your class (one bool flag "done" in this example, and one return data "street" in your example).
That is the simplest way to get what you want done. (I have very similar code in an app of my own, so I know it works)
Your code is almost right... I just changed
t.DoTask(latitude, longitude);
for
new Thread(() => t.DoTask(latitude, longitude)).Start();
TaskCompleted will be executed in the same thread as DoTask does. This should work.

Categories

Resources