Asynchronous Tasks in Silverlight
Posted July 15th, 2010 . 4 Comments .
Anyone who has developed in Silverlight knows that you can’t block the UI, silverlight actually throws an exception if you block the UI. So most tasks need to be done asynchronously, but for some strange reason I can’t find this type of functionality built into the silverlight framework, one would think that Microsoft would supply a way of doing this without having to write your own threading, something like the following:
public void LoadData()
{
int result = 0;
Task.Execute( () => result = SomeMethod(), (e) => taskComplete(e, result));
}
public int SomeMethod()
{
return 2 * (100 / 5) + 1000;
}
public void taskComplete(Exception e, int result)
{
if(e != null)
// do something with the exception.
else
// do something with the result.
}
But since I couldn’t find one in the silverlight framework, I wrote one for my own use:
public class Task<T>
{
public Task(Func<T> function, Action<T> completed)
{
_func = function;
_completed = completed;
}
private Func<T> _func;
private Action<T> _completed;
private Dispatcher _dispatcher;
public void Execute()
{
Thread thread = new Thread(Start);
thread.Start();
}
private void Start()
{
var result = _func();
_dispatcher.BeginInvoke(_completed, result);
}
}
public class Task
{
public Task(Dispatcher dispatcher, Action action, Action<Exception> completed)
{
_action = action;
_completed = completed;
_dispatcher = dispatcher;
}
public Task(Action action, Action<Exception> completed)
{
_action = action;
_completed = completed;
_dispatcher = Dispatcher.CurrentDispatcher;
}
private Dispatcher _dispatcher;
private Action _action;
private Action<Exception> _completed;
private Exception _exception;
public void Execute()
{
Thread thread = new Thread(Start);
thread.Start();
}
public static void Execute(Dispatcher dispatcher, Action action, Action<Exception> completed)
{
new Task(dispatcher, action, completed).Execute();
}
public static void Execute(Action action, Action<Exception> completed)
{
new Task(action, completed).Execute();
}
public static void Execute<T>(Func<T> action, Action<T> completed)
{
new Task<T>(action, completed).Execute();
}
private void Start()
{
try
{
_action();
}
catch (Exception ex)
{
_exception = ex;
}
_dispatcher.BeginInvoke(_completed, _exception);
}
}
All you need to do to use it, is the same as I did right at the top:
public void LoadData()
{
int result = 0;
Task.Execute( () => result = SomeMethod(), (e) => taskComplete(e, result));
}
public int SomeMethod()
{
return 2 * (100 / 5) + 1000;
}
public void taskComplete(Exception e, int result)
{
if(e != null)
// do something with the exception.
else
// do something with the result.
}
or you can do it without the complete method:
public void LoadData()
{
int result = 0;
Task.Execute(
() => result = SomeMethod(),
(e) =>
{
if(e != null) // do something with the error.
else // do something with the result.
});
}
public int SomeMethod()
{
return 2 * (100 / 5) + 1000;
}
Hope this helps someone with their silverlight UI development.
