如何使这个扩展方法编译通过?

4

我正在尝试为通用委托Action<T>创建一个扩展方法,以便能够在Action<T>方法上进行简单的异步调用。它基本上只是实现了当您想要执行该方法但不关心其进度时的模式:

public static class ActionExtensions
{
    public static void AsyncInvoke<T>(this Action<T> action, T param) {
        action.BeginInvoke(param, AsyncActionCallback, action);
    }

    private static void AsyncActionCallback<T>(IAsyncResult asyncResult) {
        Action<T> action = (Action<T>)asyncResult.AsyncState;
        action.EndInvoke(asyncResult);
    }
}

问题在于,由于额外的<T>,使得AsyncActionCallback成为泛型,并且具有与预期不同的签名,因此它无法编译。预期的签名是void AsyncActionCallback(IAsyncResult)
有人知道如何解决这个问题或实现我想做的事情吗?
3个回答

7
public static void AsyncInvoke<T>(this Action<T> action, T param)
{
    action.BeginInvoke(param, asyncResult => 
    {
        Action<T> a = (Action<T>)asyncResult.AsyncState;
        a.EndInvoke(asyncResult);
    }, action);
}

那是其中一种方式 :) 想得好。 - leppie
太棒了,非常感谢你那么快速的回答!Lambda函数使以前不可能的事情成为可能,这很有趣。我猜它并不仅仅是语法糖! - user65199
请注意,这种方法可能会导致在调用过程中发生的任何错误被忽略。您可能希望在lambda的内容中包装try {} catch {}。 - Katelyn Gadd

0
如果您想将函数保持分离(而不是作为lambda),可以考虑类似以下的代码:
public static void AsyncInvoke<T>(Action<T> action, T param)
{
    action.BeginInvoke(param, new AsyncCallback(AsyncActionCallback<T>), action);
}

0

AsyncActionCallback<T> ?

免责声明:以上内容不确定,可能是其中一种“限制”。


我不确定你的意思。我在发布的代码中使用了完全相同的签名。但是再次编译时会失败,因为编译器不希望类型参数<T>。无论如何,Darin的解决方案使用lambda而不是委托可以正常工作。 - user65199

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接