Reputation: 2165
This seems simple enough... wanting to do this in .NET 3.5 (CF compatible if possible).
I want to call a function, and pass it a callback function that it fires upon completion. How is this done?
Example code:
public static void downloadTemplateDataAsync(int officeID, int? workbookID, TemplateType templateType, int? templateID, TemplateRequestDelegate callback)
{
Template t = null;
System.Threading.Thread callingThread = System.Threading.Thread.CurrentThread;
new System.Threading.Thread(() =>
{
t = downloadTemplateData(officeID, workbookID, templateType, templateID);
// Dispatch callback
callback.Invoke(t);
}).Start();
}
Upvotes: 0
Views: 2082
Reputation: 70671
I agree with the question in the comments, why do you want to execute the delegate on the main thread? That said, if you insist it can be done in a couple of ways, both of which require you to implement some infrastructure for your main thread to allow it.
The simplest to understand is to write some explicit code to coordinate. For example, taking your original code:
public static void downloadTemplateDataAsync(int officeID, int? workbookID, TemplateType templateType, int? templateID, TemplateRequestDelegate callback)
{
Template t = null;
object o = new object();
System.Threading.Thread callingThread = System.Threading.Thread.CurrentThread;
new System.Threading.Thread(() =>
{
t = downloadTemplateData(officeID, workbookID, templateType, templateID);
// Signal completion
lock (o) Monitor.Pulse(o);
}).Start();
lock (o) Monitor.Wait(o);
callback.Invoke(t);
}
}
Note that this will block your main thread while the other thread does its work. This is pretty much always the wrong thing to do, but does literally accomplish your request.
If you want the main thread to continue working on something else, then it needs to be implemented to do that something else while also periodically checking for completion of your task, at which point it would invoke the delegate. WinForms and WPF programs have a message-pumping loop that is also used for this purpose. If you want the same behavior in your non-GUI program, you'll have to reinvent that particular wheel.
On the bright side, if you do that and at the same time implement a custom SynchronizationContext that works with your implementation, then you get the other cross-thread features of .NET essentially for free. On the not-so-bright side, doing all that is a lot of work.
Are you really really sure you need this behavior? If you explain in more detail what you're actually trying to accomplish, you might get a better answer.
Upvotes: 1