- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我目前正在处理一个从大型二进制文件读取的应用程序,该文件包含数千个文件,每个文件都由应用程序中的其他类处理。此类返回一个对象或 null。我想在主窗体上显示进度,但出于某种原因我无法理解它。
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 数据流的新手,所以我希望有人能分享一些关于为什么在第二个代码片段中有效而在第一个片段中无效的原因。
亲切的问候,马丁
最佳答案
您的 UI 被阻止的原因是因为您正在使用 FromCurrentSynchronizationContext
。它会导致代码在 UI 线程上运行,这意味着如果您正在执行一些长时间运行的操作(很可能是 GetFileFromLargeFile()
),它将卡住。
另一方面,您必须在 UI 线程上运行 lblProgress.Text
。
我不确定您是否应该直接在此代码中设置 lblProgress.Text
,这对我来说似乎耦合得太紧了。但如果你想这样做,我认为你应该只在 UI 线程上运行那一行:
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);
}
});
但更好的解决方案是让 GetFileFromLargeFile()
异步并确保它不会在 UI 线程上执行任何长时间运行的操作(ConfigureAwait(false)
可以帮助您) .如果这样做,ActionBlock
的代码可以在 UI 线程上运行而不会卡住您的 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);
关于c# - FromCurrentSynchronizationContext,我错过了什么吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10673402/
我目前正在处理一个从大型二进制文件读取的应用程序,该文件包含数千个文件,每个文件都由应用程序中的其他类处理。此类返回一个对象或 null。我想在主窗体上显示进度,但出于某种原因我无法理解它。 int
我目前正在处理一个从大型二进制文件读取的应用程序,该文件包含数千个文件,每个文件都由应用程序中的其他类处理。此类返回一个对象或 null。我想在主窗体上显示进度,但出于某种原因我无法理解它。 int
不太确定这里发生了什么- 这段代码会导致问题,因为它首先从主线程调用(在 VS 的任务 View 中验证)并安排任务,但是在 UpdateSearchCache 中设置断点时,我们现在在工作线程中 -
我在尝试运行下面的示例时遇到运行时异常。 Unhandled Exception: System.InvalidOperationException: The current Synchronizat
我在通过任务调用服务的 ViewModel 中有代码。 任务完成后,它将填充 ObservableCollection。 问题是它通过使用 ContinueWith 方法并提供 TaskSchedul
我想使用 Task 将一些文本添加到列表框中,我只需使用一个按钮并在点击事件中放置以下代码: TaskScheduler uiScheduler = TaskScheduler.FromCurrent
在加载 WPF 应用程序时存储/缓存从 TaskScheduler.FromCurrentSynchronizationContext 返回的 TaskScheduler 并从那里开始使用它是否有意义
我正在 VS2012、WPF 和 MVVM 中做一些 TPL。我有一个问题,我想我知道答案但想确定。考虑这个片段: TaskCanceller = new CancellationTokenSourc
我感兴趣的是为什么我们需要调用 InvokeOnMainThread 而这将是 TaskScheduler.FromCurrentSynchronizationContext() 的主要意图和职责?
我有一个从数据库中获取产品的任务,以及操作一些 UI 修改的 ContinueWith 操作,因此我遇到了一个问题,因为任务创建了一个新线程,并且没有执行 UI 修改在 UI 线程中。 我尝试使用此修
我们正在观察一些奇怪的事情,代码如下: var task = new Task(...); // run in the background, do something lengthy work ta
这是 this question 的后续行动. 问题:使用 async 表达以下内容的简洁方式是什么?/await而不是 .ContinueWith() ?: var task = Task.Run(
我是一名优秀的程序员,十分优秀!