Thanks to Noseratio's suggestions I actually redesigned how this done and was able to have it work without an issue. I eliminated the BackgroundWorker
object since it wasn't really necessary. Instead I wrapped the entire dataflow in an asynchronous method, which takes various Progress<T>
parameters as callbacks for progress updates. There were no extra TPL Blocks used in order to post progress since the Progress<T>
's Report()
method is called within preexisting blocks. Additionally, since this is an async function the Task that represents the dataflow is not running on the UI thread, but instead on a threadpool thread. The main thing to take from this is that the Progress<T>
objects's callbacks are run on the thread they are created on since during construction they capture the current synchronization context. Here is an example of what resolved my issue:
public static async Task ProcessData(IProgress<int> ReadProg, IProgress<int> UploadProg)
{
var loadBuffer = new BufferBlock<string>();
var parseBlock = new TransformBlock<string, MyObject>(async s =>
{
if(await DoSomething(s))
ReadProg.Report(1);
else
ReadProg.Report(-1);
});
...
//setup of other blocks
//link blocks
//feed data into pipeline by adding data into the head block: loadBuffer
//await ALL continuation tasks of the blocks
}
Then within the UI I created the Progress<int>
objects and passed them into the async ProcessData
method. Whenever the Process<T>.Report()
method were called in the async processing method the UI updated without issue.