First, I don’t think I have titled this correctly – after much thought.
However, I have been trying to find a way to update a UI control from multiple threads spawned from a Task.Run(async ()=>{ }) expression/method. I’m doing this in an UWP windows mobile 10 application.
I've listed majority of the routines involved, and need help with completing the call to the DisplayProgress(string message) method. In this method, I want to update the UI control in a thread safe manner using Dispathcer.RunAsync(), but need it to be thread safe. Please see Attempt 1&2 in the code below.
public sealed partial class SynchProcess : BasePage
{
protected override void OnNavigatedTo(NavigationEventArgs e)
{
Task.Run(async ()=>{
var result = await SynchTables();
});
}
private async Task<bool> SynchTables()
{
Bool bRet = true;
List<Task> tasks = new List<Task>();
Try
{
// Refresh 1
tasks.Add(Task.Run(async () =>
{
// Update UI
DisplayProgress(“Cars refresh…running”);
List<Car> cars = await _dataService.GetCarsData();
DataAccessSQLite.DeleteAll<Car>();
DataAccessSQLite.InsertCars(cars);
// Update UI
DisplayProgress(“Cars refresh…completed”);
}));
// Refresh 2
tasks.Add(Task.Run(async () =>
{
//Update UI
DisplayProgress(“Tracks refresh…running”);
List<Track> tracks = await _dataService.GeTrackstData();
DataAccessSQLite.DeleteAll<Track>();
DataAccessSQLite.InsertTracks(tracks);
//Update UI
DisplayProgress(“Tracks refresh…completed”);
}));
// Refresh 3
// Refresh 4
…
…
Task.WaitAll(tasks.ToArray());
}
Catch(AggreggateException agEx)
{
bRet = false;
// removed for brevity
…
}
return bRet;
}
// Attempt 1 : This i was aware of, but included for completeness.
// FAIL - The await operator can only be used in an async method.
private static void DisplayProgress(string message)
{
lock(_lockObject)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
//Update control logic;
});
}
// Attempt 2
// FAIL - An object reference is required for non-static field, method or
// property ‘DependencyObject.Dispatcher’
private static async Task DisplayProgress (string message)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
// Update UI logic here
});
}
}
I found this article http://briandunnington.github.io/uitask.html, however, I’m not sure if this approach is correct or thread safe. Seems like a lot of boilerplate code for something that should be handled by Dispatacher.RunAsync()? Additional articles I’ve read pointed to Action delegates, which I think is supposed to be thread safe, but after several (very detailed technical articles) I am now confused. Additional articles: Are C# delegates thread-safe? (unfortunately, I can only link to 2 articles - need to increase my points first !)