我目前正在从一个大的二进制文件中读取应用程序,该文件包含数千个文件,每个文件正由应用程序中的其他类处理。该类返回一个对象或null。我想在主表单上显示进度,但出于某种原因,我无法理解它。FromCurrentSynchronizationContext,我错过了什么?
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);
上面的代码冻结我的表,甚至我用“TaskScheduler.FromCurrentSynchronizationContext”,为什么呢?因为当我用我下面的表格,代码将更新精细
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);
}
});
我是新来这整个TPL数据流,所以我希望有人能分享为什么在第二代码片段它的工作原理,并在第一个片段的一些光它没有。
亲切的问候, 马亭
TNX的解释,明确给我认识。仍然有一个问题,像在第一个例子中那样在UI线程外部运行任务会更好吗?我们这样做对于应用程序的性能无关紧要吗? – Martijn
如果任务只运行很短的时间,那么它并不重要。否则,你不应该在UI线程上运行长时间运行的任务。不是因为性能,而是因为它会冻结你的应用程序。 – svick
是否有任何其他(更好)的方式来处理gui更新?我使用svick推荐的代码,但仍然是我的UI冻结..在我的应用程序中,总共有8个ActionBlock每个执行一个自定义对象的任务,3个ActionBlocks执行有一个MaxParallizism设置为处理器计数,在我的情况是7.所有8个ActionBlocks与gui进行通信......因此,理论上它可能是> 30个想要更新gui的任务。任何想法? –
Martijn