Reputation: 289
I have a list of items that need to be updated if information is missing. However, I'm making a call to Google Location services to do that. I'm wondering how I can append the necessary Lat & Long information asynchronously if possible
my code
public static void PullInfo()
{
foreach (var item in SAPItems)
{
if(item.MDM_Latitude == null || item.MDM_Longitude == null)
{
var point = GetMapPoint(item.AddressLine1 + " " + item.FiveDigitZip);
item.MDM_Latitude = point.Result.Latitude.ToString();
item.MDM_Longitude = point.Result.Longitude.ToString();
}
}
foreach(var item in SAPItems)
Console.WriteLine(item.MDM_Latitude + " " + item.MDM_Longitude);
}
private static async Task<MapPoint> GetMapPoint(string add)
{
var task = Task.Run(() => LocationService.GetLatLongFromAddress(add));
return await task;
}
Upvotes: 1
Views: 4320
Reputation: 17789
You can get multiple map points asynchronously with multiple tasks (notice that it requires to convert PullInfo()
to async-await):
public static async Task PullInfo()
{
// Create tasks to update items with latitude and longitude
var tasks
= SAPItems.Where(item => item.Latitude == null || item.Longitude == null)
.Select(item =>
GetMapPoint(item.AddressLine1 + " " + item.FiveDigitZip)
.ContinueWith(pointTask => {
item.MDM_Latitude = pointTask.Result.Latitude.ToString();
item.MDM_Longitude = pointTask.Result.Longitude.ToString();
}));
// Non-blocking await for tasks completion
await Task.WhenAll(tasks);
// Iterate to append Lat and Long
foreach(var item in SAPItems)
Console.WriteLine(item.MDM_Latitude + " " + item.MDM_Longitude);
}
private static Task<MapPoint> GetMapPoint(string add)
{
return Task.Run(() => LocationService.GetLatLongFromAddress(add));
}
If PullInfo()
cannot be converted to async-await, you can force the thread to wait for the results, but it will block the current thread:
public static void PullInfo()
{
// Create tasks to update items with latitude and longitude
var tasks
= SAPItems.Where(item => item.Latitude == null || item.Longitude == null)
.Select(item =>
GetMapPoint(item.AddressLine1 + " " + item.FiveDigitZip)
.ContinueWith(pointTask => {
item.MDM_Latitude = pointTask.Result.Latitude.ToString();
item.MDM_Longitude = pointTask.Result.Longitude.ToString();
}));
// Wait for tasks completion (it will block the current thread)
Task.WaitAll(tasks.ToArray());
// Iterate to append Lat and Long
foreach(var item in SAPItems)
Console.WriteLine(item.MDM_Latitude + " " + item.MDM_Longitude);
}
private static Task<MapPoint> GetMapPoint(string add)
{
return Task.Run(() => LocationService.GetLatLongFromAddress(add));
}
Running example of this last code sample: https://ideone.com/0uXGlG
Upvotes: 5
Reputation: 17327
You just need to await the call to getting the data (notice how the await
got moved from GetMapPoint
):
public static async Task PullInfo()
{
foreach (var item in SAPItems)
{
if(item.Latitude == null || item.Longitude == null)
{
var point = await GetMapPoint(item.AddressLine1 + " " + item.FiveDigitZip);
item.MDM_Latitude = point.Latitude.ToString();
item.MDM_Longitude = point.Longitude.ToString();
}
}
foreach(var item in SAPItems)
Console.WriteLine(item.MDM_Latitude + " " + item.MDM_Longitude);
}
private static Task<MapPoint> GetMapPoint(string add)
{
var task = Task.Run(() => LocationService.GetLatLongFromAddress(add));
return task;
}
You're not modifying your SAPItems
collection, just each individual item. Once you have the response, you can just update the then-current item in the loop.
Upvotes: 1