c# - SynchronizationContext.Send 和 SynchronizationContext.Post 有什么区别?

标签 c# multithreading threadpool conceptual synchronizationcontext

感谢 Jeremy Miller 在 Functional Programming For Everyday .NET Development 中的出色工作,我有一个工作命令执行器,它可以做我想做的一切(在线程池上做繁重的工作,将结果或错误发送回同步上下文,甚至将进度发送回同步上下文),但我无法解释为什么使用 SynchronizationContext.Send来自线程池和Synchronization.PostFunc 传递到执行繁重工作的方法。我已经多次阅读文档,但我无法直觉了解其中的区别。我应该从一个名为 Send 和一个名为 Post 的事实中得到什么?我感觉到神奇之处在于 Send “启动一个同步 请求”和 Post “启动一个异步 请求",但这两个请求都来自线程池,需要发送/回发到 UI 线程。

谁能解释一下其中的区别,即使它只是一种让我知道何时选择一个而不是另一个的助记设备?

以防万一,这是我的测试代码,我在其中使用Post 将进度发送回 UI:

private Action _ExecuteCommand
                (SynchronizationContext context
                 , Action<int, int> progress
                 , Action<int, int> after)
{
    int count = 3;
    int accumulatedValue = 0;
    int threadId = Thread.CurrentThread.ManagedThreadId;
    for (int i = 0; i < count; i++)
    {
        Thread.Sleep(1000);
        context.Post(delegate { progress(i + 1, threadId); });
        accumulatedValue += i;
    }

    return () => after(threadId, accumulatedValue);
}

_ExecuteCommand 方法作为下面的 command 参数传入,大部分来自原始文章,它使用 Send 发送完成和错误返回给 UI 的消息:

public void Execute(Func<Action> command, Action<Exception> error)
{
    ThreadPool.QueueUserWorkItem(o =>
     {
         try
         {
             Action continuation = command();
             _Context.Send(s => continuation());
         }
         catch (Exception e)
         {
             _Context.Send(s => error(e));
         }
     });
}

最佳答案

发送 - 同步:WAITING应答(或 Action 完成)

后 - 异步:放下并继续

因此,您的示例在正确的时刻使用了正确的方法。在进度更新完成之前无需停止 for 循环(相反)。
而Execute确实要等待Action完成,否则异常处理没有意义。

关于c# - SynchronizationContext.Send 和 SynchronizationContext.Post 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2473073/

相关文章:

c# - 填充可为空的小数时,小数会四舍五入,为什么?

c# - 尝试将对象添加到类中的列表时出现 "Object reference not set to an instance of an object"错误

c# - 2个线程同时进入一个锁定的代码块

c# - System.Net.SmtpClient SendAsync() 方法的内部实现

c# - 如何在标签中显示日期

java - 线程的 String 字段上的 getter 和 setter 是否必须同步/

c++ - 在别人的地址空间中线程化

python - 多重处理似乎根本不起作用?

Java-线程池

c# - 对象的无赋值构造有意义吗?