如何通过对目标的弱引用将操作传递给任务工厂

发布于 2025-01-05 05:40:07 字数 964 浏览 5 评论 0原文

编辑:我更新了我的代码。这能达到我的目标吗?

我有一组用于异步调用方法的工作方法,但我对通过 lambda 传入的引用有一个特定的问题。具体来说,我有一个(子)窗口,它启动一个操作并注册一个回调。正如您所料,即使我关闭此窗口,它仍然会被调用。

我想要做的是传递一种“弱引用”或从传入的操作中构造一个弱引用。

这就是我构建 Action 的方式(示例代码):

static Action CreateNewAction(Action call, Action<SomeArg> callback, 
    Dispatcher dispatcher)
{
    return delegate {
        try
        {
            call();

            var target = callback.Target
            if(target != null)
                dispatcher.Invoke(callback, new SomeArg());
    }
        catch (Exception ex)
        {
            // handle the ex in some way..
        }
    };
}

这就是任务工厂调用它的方式:

var t = Task.Factory.StartNew(CreateNewAction(call, callback, dispatcher))

这就是我调用它的方式(调用只是将操作和回调传递给任务工厂,如上所示) ):

WeakReference wr = new WeakReference(myTarget);
StartMyTaskAsync(someAction, ((MyTargetClass)wr.Target).SomeCompletedFunc);

Edit: I updated my code. Would this achieve what i am aiming for?

I have a working set of methods for async calling of methods but i have a specific problem with the references i pass in via a lambda. Specifically i have a (child) window that starts an operation and registers a callback. As you might expect, even when i close this window it still gets invoked.

What i want to do is pass in a kind of "weak reference" or construct a weak reference out of the incoming action.

Thhis is the way i build my Action (example code):

static Action CreateNewAction(Action call, Action<SomeArg> callback, 
    Dispatcher dispatcher)
{
    return delegate {
        try
        {
            call();

            var target = callback.Target
            if(target != null)
                dispatcher.Invoke(callback, new SomeArg());
    }
        catch (Exception ex)
        {
            // handle the ex in some way..
        }
    };
}

And this is how the task factory calls it:

var t = Task.Factory.StartNew(CreateNewAction(call, callback, dispatcher))

And this is how I would call it (the call just basses both the action and the callback through to the task factory as seen above):

WeakReference wr = new WeakReference(myTarget);
StartMyTaskAsync(someAction, ((MyTargetClass)wr.Target).SomeCompletedFunc);

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

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

发布评论

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

评论(1

紫南 2025-01-12 05:40:07

问题来自这一行:

StartMyTaskAsync(someAction, ((MyTargetClass)wr.Target).SomeCompletedFunc);

具体来说,这部分:

((MyTargetClass)wr.Target).SomeCompletedFunc

您正在具体化 WeakReference 在您想要实际检查 WeakReference 是否已释放 lambda/委托之前就获取 lambda/委托引用的方法<一href="http://msdn.microsoft.com/en-us/library/system.weakreference.target.aspx" rel="nofollow">目标

你真正想做的是为你的委托传递一个包装器,就像这样(你没有显示 SomeCompletedFunc 的签名,所以我不知道调用会是什么样子,我'出于本问题的目的,我假设它是一个无参数的 void 方法):

StartMyTaskAsync(someAction, () => {
    // Check the weak reference.  If null, return.
    var target = wr.Target as MyTargetClass;

    // If null, return.
    if (target == null) return;

    // If not null, call.
    target.SomeCompletedFunc();
});

这样,您可以在想要创建方法调用,而不是在分配回调时调用。

The problem comes from this line:

StartMyTaskAsync(someAction, ((MyTargetClass)wr.Target).SomeCompletedFunc);

Specifically, this part:

((MyTargetClass)wr.Target).SomeCompletedFunc

You are materializing the target of the WeakReference to get the method that is referenced by the lambda/delegate long before you want to actually check whether or not the WeakReference has let go of the Target.

What you really want to do is pass a wrapper for your delegate, something like this (you didn't show the signature of SomeCompletedFunc so I don't know exactly what the call will be like, I'm assuming it's a parameterless void method for the purposes of this question):

StartMyTaskAsync(someAction, () => {
    // Check the weak reference.  If null, return.
    var target = wr.Target as MyTargetClass;

    // If null, return.
    if (target == null) return;

    // If not null, call.
    target.SomeCompletedFunc();
});

This way, you check the Target of the WeakReference at the time you want to make the method call, and not when you assign the callback.

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