I've been trying to figure out how to return data in type Task other than an int like this for example, Task<Dictionary<string, string>>.
All the examples I seem to find all show returning an Task<int>. which is easy enough to do by saying return 42;.
The function I've been trying to write works something like this:
Task<Dictionary<string, string>> getDamaged()
{
Task<Dictionary<string, string>> d = new Task<Dictionary<string, string>>();
Dictionary<string, string> e = new Dictionary<string, string>();
foreach (Building i in buildingArray)
{
if (Convert.ToInt32(i.efficiency) < 100)
{
e.Add(i.buildingID, i.buildingName);
//d.Add(i.buildingID, i.buildingName); // this does not work, either
}
}
I found the Task.FromResult method which looked somewhat promising, but further investigation appears to show that TResult as a completed task which to me sounds not necessarily like one that you can await.
Any ideas on how to get this working correctly?
Update
The point of this method is I am trying to offload work from my UI thread to keep my UI responsive. This is one of my first attempts at really trying to do this using visual studio 2012 with .net4.5. The code above I wrote from memory. I'll post the actual code I've been attempting along with commented out failed attempts.
One part that really bugs me is that if I return a int if my return type is task, but if I try with dictionary I get an error about cannot implicitly convert a dictionary to a task
private Task<Dictionary<string, string>> GetDamagedBuildings()
{
//Task<Dictionary<string, string>> damagedBuildings = new Task<Dictionary<string,string>>();
Dictionary<string, string> d = new Dictionary<string, string>();
foreach (ButtonPlanetMap i in buttonArray)
{
//Dictionary<string, string> d = new Dictionary<string,string>();
if (Convert.ToInt32(i.efficiency) < 100)
{
d.Add(i.buildingID.ToString(), i.buildingName);
//(Dictionary<string, string>)damagedBuildings.
}
}
//damagedBuildings = Cast d;
//return damagedBuildings;
return d;
}
There is nothing special about int, you can return a Dictionary from your method exactly the same way.
What exactly you should do depends on why does your method return a Task.
Task, don't return a Task, return the Dictionary directly.Task to fulfill an interface, but you don't actually want to make your method asynchronous, Task.FromResult() is a good solution. You can use it something like this: return Task.FromResult(dictionary);. Such Task can still be awaited, it's just that the await will complete immediately.If you're returning a Task because your method is CPU intensive and you want to execute it on a background thread, then you should use Task.Run():
return Task.Run(() =>
{
var dictionary = new Dictionary<string, string>();
…
return dictionary;
});
But doing this is often not a good idea, see Should I expose asynchronous wrappers for synchronous methods?
Using Task.FromResult will mean your method runs synchronously and then return a completed task, which is probably not what you intend (although you can await a completed task).
You can start a new task using TaskFactory.StartNew. If you are using .Net 4.5, you can use Task.Run instead which uses TaskFactory.StartNew with some common default arguments.
Task<Dictionary<string,string>> GetDamaged()
{
return Task.Factory.StartNew(() => {
Dictionary <string, string> e = new Dictionary<string, string>();
foreach(Building i in buildingArray)
{
if(Convert.ToInt32(i.efficiency) < 100)
{
e.Add(i.buildingID, i.buildingName);
}
}
return e;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With