问题标签 [synchronizationcontext]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
213 浏览

c# - TaskScheduler - 执行延续

在阅读了一些关于TaskScheduler这里的好文章)之后,事实证明一个TaskScheduler可以:

  1. 调度任务 - 通过使用QueueTask方法,在上面的示例中只是Post将任务执行到选定的SynchronizationContext

  2. 通过与当前运行的框架 ( ) 关联的较低级别的调度程序来调度延续SynchronizationContext

2. 是否与CotninueWith方法有关Task?我显然理解 1.,但不明白 2. 如何适用于TaskScheduler. 会以什么方式TaskScheduler发生?

0 投票
0 回答
956 浏览

c# - TaskScheduler.TryExecuteTaskInline - 相同的线程或上下文?

TryExecuteTaskInline 的 MSDN 文档指出:

派生自 TaskScheduler 的类实现此函数以支持在启动对该任务对象的等待的线程上内联执行任务。

但是,如果您查看源代码,则执行TaskScheduler.TryExecuteTaskInline

仅检查当前同步上下文是否与实例化期间捕获的同步上下文相同(请参阅SynchronizationContextTaskScheduler同一源文件中的构造函数)。多个线程可以共享一个同步上下文,所以不一定是同一个线程。

因此,要么我实际上不了解文档中的内容,要么是错误的。谁能解释一下?

我只是看不到该实现如何“支持在启动该任务对象的等待的线程上内联执行任务。”,正如该方法的文档所要求的那样。它只是调用 TryExecuteTask,后者调用任务的 ExecuteEntry(您只需单击方法名称即可跳转到其源)。

0 投票
1 回答
1035 浏览

c# - 当前的 SynchronizationContext 可以为空吗?

https://msdn.microsoft.com/en-us/magazine/gg598924.aspx

这是一篇很棒的文章,我知道无法涵盖所有​​细节,因为这基本上涉及粘贴 .NET 框架的源代码。所以引用正文:

每个线程都有一个当前上下文。如果“Current”为空,则按照惯例,线程的当前上下文是“new SynchronizationContext()”。

然而,另一方面:

默认情况下,当前的 SynchronizationContext 是在 await 点捕获的,这个 SynchronizationContext 用于在 await 之后恢复(更准确地说,它捕获当前的 SynchronizationContext 除非它是 null,在这种情况下它捕获当前的 TaskScheduler)

这两个陈述几乎相互矛盾,所以我认为这是作者所做的一些简化的结果(我很好)。

谁能解释一下?可能有助于回答我的问题的代码(查找变量syncCtx),这段代码与第二个引用有关。

0 投票
0 回答
207 浏览

task - TaskScheduler.FromCurrentSynchronizationContext() 使我的应用程序崩溃

我有一个控制台应用程序,我的第一行在 Main 方法中是:

但是在这里我的应用程序崩溃了System.InvalidOperationException:附加信息:当前SynchronizationContext可能不能用作TaskScheduler. 我在 MSDN 上搜索过,但没有找到此方法的文档。我做错了什么?

0 投票
2 回答
1096 浏览

c# - 如何对衍生 Task.ContinueWith 的方法进行单元测试?

考虑以下代码:

如何对 Foo.AddContent 方法进行单元测试?我想测试我的模拟 IBar 提供的字符串实际上是否被添加到集合中,但是断言总是在任务更新集合之前被调用。

我正在使用 .NET 4.5.2。我的第一选择是在 AddContent 中使用asyncand await,但是因为在构造函数中使用了该方法,所以我认为最好避免这种情况。我需要一些可以启动数据异步加载但不会等待它完成的东西。

欢迎提出关于如何重写 AddContent 的建议,但我已经尝试了很多东西,这是唯一一个运行良好的东西,所以我真正想要的是一种测试它的方法。

0 投票
2 回答
498 浏览

c# - Async-Await 在预期出现死锁的地方没有死锁

众所周知,异步方法上的同步等待会导致死锁(例如,请参阅Don't Block on Async Code

我在 Windows 窗体应用程序中单击按钮的事件处理程序中有以下代码(即在SynchronizationContext安装 UI 的情况下调用代码)。

我完全期望代码在单击按钮时死锁。但是,我实际看到的是同步等待——对话框有一段时间没有响应,然后像往常一样接受事件。当我尝试同步等待客户端异步方法时,我一直看到死锁。但是,同步等待异步方法,例如死锁SendAsyncReadAsByteArrayAsync似乎不会死锁。有人可以解释这种行为吗?

.NET 库中的异步方法的实现是否在内部使用 await 语句,因此必须将延续编组回原始 SynchronizationContext?

注意:如果我定义了一个客户端方法,比如说

然后byte[] byteArray = wrapperMethod().Result;在按钮单击处理程序中说,我确实遇到了死锁。

0 投票
2 回答
798 浏览

wpf - 异步回调中的 SynchronizationContext.Current

对于 WinForms 和 WPF,我将SynchronizationContext其用作与 GUI 线程同步的一种方式。最近我遇到了旧式异步回调的问题:

这会抛出异常,因为SynchronizationContext.Current回调函数中的 等于捕获的,因此 UI 操作是在回调的工作线程中执行的。

在 WinForms 中使用这个完全相同的代码就像我预期的那样工作。

现在作为一种解决方法,我正在捕获当前ManagedThreadId并在回调中进行比较。处理此问题的正确方法是什么?

更新:

我应该补充一点,我正在修改一个非常古老的现有类,该类当前使用以下构造:

我正在尝试删除 WinForms 依赖项,而不会对此类的客户端产生太大影响。这SomeFunction()是引发事件,所以如果我只是调用 uiContext.Send() 或 uiContext.Post() ,执行顺序会改变,因为 Post() 将始终排队调用,而 Send() 将始终阻塞。

此外,这只是一小段代码,用于显示我的问题的根源。实际上,可以从主线程调用执行 Post() 的函数。

这是针对 .NET 4.0

0 投票
2 回答
331 浏览

c# - SynchronizationContext 和 DispatcherUnhandledException

我遇到了这样一种情况,即 UI 线程中引发的异常没有在调用线程中被捕获。

首先,我认为这是不可能的(我发现的所有文档都说我可以在那里捕获异常)。经过一番研究,我发现了问题:我的应用程序使用了 UnhandledExceptionHandler。处理DispatcherUnhandledException-Event。我正在向用户显示一些信息并设置e.Handled = true;

所以问题是:为什么DispatcherUnhandledException即使我处理它也会引发 -Event ?你将如何解决这种情况?

0 投票
0 回答
419 浏览

wpf - 为什么我们需要在 WPF 的 EventAggregator 中使用 SynchronizationContext

我已经阅读了一些 EventAggregator (Messenger) 的实现来在 WPF 中的不同 ViewModel 之间进行通信,但是我很难理解为什么我们必须使用SynchronizationContext.

我了解SynchronizationContext用于确保 Post/Send 操作在同一上下文的线程上运行。在 EventAggregator 的情况下它提供了什么优势。相反,如果不使用 a ,有人可以提供 EA 将失败的示例SynchronizationContext

0 投票
2 回答
4169 浏览

c# - 如何获取特定 WPF 窗口的当前 SynchronizationContext?

好的,我在这里有点困惑。SynchronzationContext浏览与DispatcherSynchronizationContext. 以下是 MSDN 杂志关于此类的摘录:

DispatcherSynchronizationContext (WindowsBase.dll: System.Windows.Threading) WPF 和 Silverlight 应用程序使用 DispatcherSynchronizationContext,它将委托以“正常”优先级排列到 UI 线程的 Dispatcher。当线程通过调用 Dispatcher.Run开始其 Dispatcher 循环时,此 SynchronizationContext 被安装为当前上下文。DispatcherSynchronizationContext 的上下文是单个 UI 线程。

排队到 DispatcherSynchronizationContext 的所有委托由特定的 UI 线程按照它们排队的顺序一次执行一个。当前实现为每个顶级窗口创建一个 DispatcherSynchronizationContext,即使它们都共享相同的底层 Dispatcher。

(从这里:https ://msdn.microsoft.com/magazine/gg598924.aspx )

让我感到困惑的是,我用粗体/斜体表示的两个部分似乎相互矛盾。第一个似乎DispatcherSynchronizationContext是每个线程创建一个并设置为线程的当前同步上下文。但是,第二个摘录说每个窗口DispatcherSynchronizationContext都创建一个,即使它们都共享相同的调度程序/UI 线程。

我错过了什么/不理解什么?

如果它真的是每个窗口一个,而不仅仅是每个线程,你如何获得DispatcherSynchronizationContext特定窗口的?