FromCurrentSynchronizationContext, am I missing something?
c#, task-parallel-library, tpl-dataflow, user-interface
Solution
The reason your UI is blocked is becase you're using `FromCurrentSynchronizationContext`. It causes the code to run on the UI thread, which means it will freeze if you're doing some long running action (most likely `GetFileFromLargeFile()`).
On the other hand, you have to run the `lblProgress.Text` on the UI thread.
I'm not sure you should set `lblProgress.Text` directly in this code, it look like too tight coupling to me. But if you want to do that, I think you should run just that line on the UI thread:
var producer = new ActionBlock<someObject>(async largeFile =>
{
var file = GetFileFromLargeFile(largeFile);
if (file != null)
{
TotalFound++;
await buffer.SendAsync(file);
await Task.Factory.StartNew(
() => lblProgress.Text = String.Format("{0}", TotalFound),
CancellationToken.None, TaskCreationOptions.None, uiScheduler);
}
});
But even better solution would be if you made `GetFileFromLargeFile()` asynchronous and made sure it doesn't do any long-running actions on the UI thread (`ConfigureAwait(false)` can help you with that). If you did that, the code of the `ActionBlock` could run on the UI thread without freezing your UI:
var producer = new ActionBlock<someObject>(async largeFile =>
{
var file = await GetFileFromLargeFile(largeFile);
if (file != null)
{
TotalFound++;
await buffer.SendAsync(file);
lblProgress.Text = String.Format("{0}", TotalFound)
}
}, options);
Problem
I current working an application that reads from a large binary file, which holds several thousands files, every file is being processed by some other class in application. This class returns either an object or null. I want to show a progress on the main form but for some reason I can't get my head around it. ``` int TotalFound = 0; var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext; BufferBlock<file> buffer = new BufferBlock<file>(); DataflowBlockOptions options = new DataflowBlockOptions(){ TaskScheduler = uiScheduler, }; var producer = new ActionBlock<someObject>(largeFile=>{ var file = GetFileFromLargeFile(largeFile); if(file !=null){ TotalFound++; buffer.post(file); lblProgress.Text = String.Format("{0}", TotalFound); } }, options); ``` The above code freezes my Form, even do I use "TaskScheduler.FromCurrentSynchronizationContext", why? Because when I use the code below my form updates fine ``` DataflowBlockOptions options = new DataflowBlockOptions(){ TaskScheduler = uiScheduler, }; var producer = new ActionBlock<someObject>(largeFile=>{ var file = GetFileFromLargeFile(largeFile); if(file !=null){ Task.Factory.StartNew(() => { TotalFound++; buffer.Post(file); }).ContinueWith(uiTask => { lblProgress.Text = String.Format("{0}", TotalFound); },CancellationToken.None, TaskContinuationOptions.None, uiScheduler); } }); ``` I am new to this whole TPL Dataflow, so I am hoping someone could share some light on why in the second code snippet it works and in the first snippet it doesn't. Kind regards, Martijn