类似于线程编组的框架

发布于 2024-12-21 21:20:06 字数 420 浏览 0 评论 0原文

我一直认为我可以使用 SynchronizationContext 来封送对另一个线程的调用。显然我错了,因为 SyncCtx.Send() 除了调用给定的委托之外什么也不做(保持在同一线程上)。我真的需要从 SynchronizationContext 派生并在线程上下文上工作吗?我感觉好像错过了什么。

我想要实现的目标:想象一个用于在应用程序中执行命令的小 API。您还可以在后台线程上执行命令,因为您可以指定委托在命令执行完成后运行。这个“完成后呼叫我”委托获取一个参数(状态),其中包含成功/失败标志、可选异常信息等。我想在原始调用线程上调用此委托,以便使用该库的开发人员不会这样做需要处理所需的调用等。我只想将其拿走并让他们进行简单的非线程感知编程。如果您不将某些控制权作为目标,WindowsFormsSynchronizationContext 似乎也没有帮助。

感谢您的帮助!

I always thought I could use SynchronizationContext to marshal a call to another thread. Apparently I was wrong as SyncCtx.Send() doesn't do anything but invoking the given delegate (stays on the same thread). Do I really need to derive from SynchronizationContext and do work on the thread context? I feel like missing something.

What I want to achive: Imagine a little API for executing commands within an app. You can also execute a command on a background thread, as you can assign a delegate to run when the command has finished execution. This "Call-me-when-done"-Delegate gets one single paramter (State) containing success/failure flag, optional exception information, etc. I want to call this delegate on the original calling thread so that devs using the lib do not need to handle invoke required etc. I would just like to take this away and let them do simple non-thread-aware programming. WindowsFormsSynchronizationContext doesn't seem to help either if you don't give it some control as a target.

Thanks for any help!

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

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

发布评论

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

评论(1

酒与心事 2024-12-28 21:20:06

当您在 winform 中并且使用同步上下文时,调用将被编组到 GUI 线程。

对于您的具体情况,我想这样的东西应该可以工作,创建一个代表您像这样创建的 Command 的类可能是个好主意

public class CommandManager
{
    private readonly SynchronizationContex _synchronizationContex;

    public CommandManager(SynchronizationContext synchronizationContex)
    {
        _synchronizationContex = synchronizationContex;
    }

    public void ExecuteAsync(Func<State> action, Action<State> callback)
    {
        ThreadPool.QueueUserWorkItem(o => {
                                             state = action();
                                             _synchronizationContex.Send(oo => callback(state));
                                          });
    } 
}

(在 GUI 线程中,例如在你的主要形式)

var commandManager = new CommandManager(SynchronizationContext.Current);

你可以像这样使用它:

commandManager.ExecuteAsync(() => new State() { Success = true }, 
                             c => MessageBox.Show("success in the GUI thread"));

When you are in winforms and you use the synchronizationcontext the call will be marshalled to the GUI thread.

for your specific case I guess something like this should work, probably it will be a good idea to create a class that represents a Command

public class CommandManager
{
    private readonly SynchronizationContex _synchronizationContex;

    public CommandManager(SynchronizationContext synchronizationContex)
    {
        _synchronizationContex = synchronizationContex;
    }

    public void ExecuteAsync(Func<State> action, Action<State> callback)
    {
        ThreadPool.QueueUserWorkItem(o => {
                                             state = action();
                                             _synchronizationContex.Send(oo => callback(state));
                                          });
    } 
}

you'd create like this (in the GUI thread, so for example in your main form)

var commandManager = new CommandManager(SynchronizationContext.Current);

you'd use it like this:

commandManager.ExecuteAsync(() => new State() { Success = true }, 
                             c => MessageBox.Show("success in the GUI thread"));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文