Tag: synchronizationcontext

ConfigureAwait(false)导致错误而不是死锁的情况

假设我编写了一个依赖于async方法的库: namespace MyLibrary1 { public class ClassFromMyLibrary1 { public async Task MethodFromMyLibrary1(string key, Func<string, Task> actionToProcessNewValue) { var remoteValue = await GetValueByKey(key).ConfigureAwait(false); //do some transformations of the value var newValue = string.Format(“Remote-{0}”, remoteValue); var processedValue = await actionToProcessNewValue(newValue).ConfigureAwait(false); return string.Format(“Processed-{0}”, processedValue); } private async Task GetValueByKey(string key) { //simulate time-consuming operation await Task.Delay(500).ConfigureAwait(false); return string.Format(“ValueFromRemoteLocationBy{0}”, […]

如何为显示的第二个表单获取同步上下文

[编辑]改编和简化整篇文章[/编辑] 在这篇博客中 ,以下(我简化了一下)作为使用SynchronizationContext对象在UI线程上运行Task的示例: Task.Factory.StartNew(() =>”Hello World”).ContinueWith( task => textBox1.Text = task.Result, TaskScheduler.FromCurrentSynchronizationContext()); 我可以在一个新项目中重复这些结果,安全地更新UI,但出于任何原因,在我当前的项目中(尽管它已经工作)我不能。 我得到标准“你不允许从错误的线程更新UI”exception。 我的代码(在MainForm_Load(…)中)是这样的,它在一个新的Project中工作,并且textBox1添加到主窗体中,但在我当前的项目中不起作用: var one = Task.Factory.StartNew( () => “Hello, my name is Inigo Montoya”); var two = one.ContinueWith( task => textBox1.Text = one.Result, TaskScheduler.FromCurrentSynchronizationContext()); 任何人都有任何关于可能是什么的想法。 [编辑] 我已经将错误追溯到对象的实例化,该对象使用表单来提示用户输入登录信息。 只有在显示表单时才会出现错误。 (如果我在Form’s Show发生之前返回一个硬编码的值,整个过程都可以正常工作)。 新问题:如果自己的构造函数在显示之前显示另一个表单,我如何获取正在构建的表单的SynchronizationContext? 以下是如何重现正在发生的事情: 1)创建两个表单:Form1带有TextBox ,Form2带有Button 2)创建一个OwnedBy1Uses2类 Form1 : public partial class Form1 : […]

比较SynchronizationContext

如何比较SynchronizationContext? 在使用BeginInvoke时,似乎同一个Dispatcher可以创建不同的SynchronizationContext。 当我深入研究两个(不相等的)上下文时,我看到调度程序的线程ID是相同的,但它们彼此不相等。 public partial class MainWindow : Window { private SynchronizationContext contexta; private SynchronizationContext contextb; private SynchronizationContext contextc; private SynchronizationContext contextd; public MainWindow() { InitializeComponent(); contexta = SynchronizationContext.Current; Loaded += MainWindow_Loaded; } private void MainWindow_Loaded(object sender, RoutedEventArgs e) { contextb = SynchronizationContext.Current; Dispatcher.Invoke(() => { contextc = SynchronizationContext.Current; }); Dispatcher.BeginInvoke(new Action(() => { contextd […]

如何解释await / async同步上下文切换行为

有几件事(但主要的一点)我不明白以下代码的行为。 有人可以帮忙解释一下吗? 它实际上是非常简单的代码 – 只是一个调用异步方法的常规方法。 在异步方法中,我使用using块尝试临时更改SynchronizationContext。 在代码的不同点,我探测当前的SynchronizationContext。 这是我的问题: 当执行到达位置“2.1”时,上下文已变为上下文#2。 好的。 然后,因为我们点击`await`,返回一个Task并执行跳回到位置“1.2”。 为什么那么,在位置1.2,上下文不会“粘”在上下文#2? 也许使用using语句和异步方法会有一些魔力吗? 在2.2位,为什么上下文不是Context#2? 上下文是否应该转入“延续”(“等待”之后的陈述)? 码: public class Test { public void StartHere() { SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); this.logCurrentSyncContext(“1.1”); // Context #1 Task t = f(); this.logCurrentSyncContext(“1.2”); // Context #1, why not Context #2? t.Wait(); this.logCurrentSyncContext(“1.3”); // Context #1 } private async Task f() { using (new […]

等待不使用当前的SynchronizationContext

在异步函数中使用不同的SynchronizationContext而不是外部时,我会遇到令人困惑的行为。 我程序的大多数代码都使用自定义的SynchronizationContext,它只是将SendOrPostCallbacks排队并在我主线程中的特定已知点调用它们。 我在开始的时候设置了这个自定义的SynchronizationContext,当我只使用这个时,一切正常。 我遇到的问题是我有函数,我希望他们等待继续在线程池中运行。 void BeginningOfTime() { // MyCustomContext queues each endOrPostCallback and runs them all at a known point in the main thread. SynchronizationContext.SetSynchronizationContext( new MyCustomContext() ); // … later on in the code, wait on something, and it should continue inside // the main thread where MyCustomContext runs everything that it has queued […]

我怎么能强制等待继续在同一个线程?

await不保证在生成任务的同一任务上继续: private void TestButton_Click(object sender, RoutedEventArgs e) { Task.Run(async () => { Debug.WriteLine(“running on task ” + Task.CurrentId); await Task.Delay(TimeSpan.FromMilliseconds(100)); Debug.WriteLine(“running on task ” + Task.CurrentId); }); } 这个输出是: running on task 1 running on task 所以我们可以看到,不仅执行已经移动到另一个任务,而且还移动到UI线程。 如何创建专用任务,并强制等待始终继续执行此任务? 长时间运行的任务也不会这样做。 我已经看过几个SynchronizationContext实现 ,但到目前为止它们都没有工作,在这种情况下因为它使用线程而System.Threading.Thread不适用于uwp。

async / await with ConfigureAwait的continueOnCapturedContext参数和SynchronizationContext用于异步延续

我想先把代码放一下,然后解释一下情况并根据这个问题提出我的问题: public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private async void Button_Click_2(object sender, RoutedEventArgs e) { var result = await GetValuesAsync(); Foo.Text += result; } public async Task GetValuesAsync() { using (var httpClient = new HttpClient()) { var response = await httpClient .GetAsync(“http://www.google.com”) .ConfigureAwait(continueOnCapturedContext: false); // This is the continuation […]

SynchronizationContext.Send和SynchronizationContext.Post有什么区别?

感谢Jeremy Miller在日常.NET开发的function编程方面所做的出色工作,我有一个工作的命令执行器,可以完成我想要的所有工作(对线程池进行繁重的工作,将结果或错误发送回同步环境,甚至发布回到同步上下文),但我无法解释为什么它使用来自线程池的SynchronizationContext.Send和来自Func Synchronization.Post传递给执行繁重工作的方法。 我已经多次阅读过这些文档,但是我无法直截了当地了解它的区别。 我应该从一个名为Send的事实中得到什么,一个叫做Post ? 我感觉神奇的是Send “启动同步请求”和Post “启动异步请求”,但这两个请求都来自线程池,需要发送/发回到UI线程。 有人可以解释这个区别,即使它只是一个助记符设备让我知道何时选择一个而不是另一个? 如果重要,这是我的测试代码 ,我使用Post将进度发送回UI: private Action _ExecuteCommand (SynchronizationContext context , Action progress , Action after) { int count = 3; int accumulatedValue = 0; int threadId = Thread.CurrentThread.ManagedThreadId; for (int i = 0; i after(threadId, accumulatedValue); } _ExecuteCommand方法作为下面的command参数传入,主要来自原始文章,它使用Send将完成和错误消息发送回UI: public void Execute(Func command, Action error) { ThreadPool.QueueUserWorkItem(o => […]

从给定的线程获取SynchronizationContext

我似乎没有找到如何获取给定Thread的SynchronizationContext : Thread uiThread = UIConfiguration.UIThread; SynchronizationContext context = uiThread.Huh?; 我为什么需要那个? 因为我需要从前端应用程序的不同位置发布到UIThread。 所以我在名为UIConfiguration的类中定义了一个静态属性。 我在Program.Main方法中设置了这个属性: UIConfiguration.UIThread = Thread.CurrentThread; 在那一刻我可以肯定我有正确的线程,但是我不能设置像这样的静态属性 UIConfiguration.SynchronizationContext = SynchronizationContext.Current 因为尚未安装该类的WinForms实现。 由于每个线程都有自己的SynchronizationContext,因此必须可以从给定的Thread对象中检索它,否则我完全错了?

解决.NET 4.0中SynchronizationContext.Current为空的问题

在.NET 4.0的主线程上, SynchronizationContext.Current意外为空的问题的解决方法是什么? 看到: 在主UI线程的Continuation中,SynchronizationContext.Current为null