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

发布于 2024-08-25 12:09:40 字数 1938 浏览 4 评论 0原文

感谢 Jeremy Miller 在日常 .NET 开发的函数式编程中所做的出色工作,我有一个工作命令执行器,可以执行我想要的所有操作(在线程池上执行繁重的工作,将结果或错误发送回同步上下文,甚至将进度发布回同步上下文),但我无法解释原因它使用线程中的 SynchronizationContext.Send -池和 Synchronization.Post 来自 Func 传递到执行繁重工作的方法中。我已多次阅读该文档,但我无法直观地了解其中的区别。我应该从一个名为 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));
         }
     });
}

Thanks to Jeremy Miller's good work in Functional Programming For Everyday .NET Development, I have a working command executor that does everything I want it to (do heavy lifting on the thread pool, send results or errors back to the synchronization context, and even post progress back to the synchronization context), but I can't explain why it uses SynchronizationContext.Send from the thread-pool and Synchronization.Post from the Func passed into the method that does the heavy lifting. I have read the documentation, several times, but I just can't get a gut sense for what the difference is. What am I supposed to get from the fact that one is called Send and one is called Post? I sense the magic is in the fact Send "starts a synchronous request" and Post "starts an asynchronous request", but both requests come from the thread pool and need to be sent/posted back to the UI thread.

Can someone explain the difference, even if it is just a mnemonic device that lets me know when to choose one over the other?

In case it matters, this is my test code where I use Post to send progress back to the 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);
}

That _ExecuteCommand method is passed in as the command parameter below, mostly from the original article, that uses Send to send completion and error message back to the 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));
         }
     });
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

迷路的信 2024-09-01 12:09:40

发送 - 同步:等待答案(或操作完成)

后 - 异步:放弃并继续

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

Send - synchronous: wait for answer (or action completed)

Post - asynchronous: drop off and continue

So your example uses the correct methods at the right moments. There is no need to halt the for-loop until the progress update is complete (on the contrary).
And Execute does want to wait for the Action to complete, otherwise the exception handling has no purpose.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文