为什么 Visual Studio 2010 告诉我“System.Delegate”?不包含“EndInvoke”的定义?

发布于 2024-12-21 03:49:20 字数 2665 浏览 1 评论 0原文

当我调用 job.Delegate.EndInvoke() 时,为什么 Visual Studio 2010 告诉我“'System.Delegate' 不包含 'EndInvoke' 的定义”?我该如何修复它?请注意,它喜欢 BeginInvoke() 就很好,并且如果我在 BeginInvoke() 之后立即添加 EndInvoke() 也不会抱怨(思考帽没有实现我想要的)。

我有一个用于跟踪备份作业的 JobTracker 类:

public class JobTracker 
{
    private class Job
    {
        public Account Account { get; set; }
        public IAsyncResult Result { get; set; }
        public Delegate Delegate { get; set; }
        public bool IsCompleted { get { return result.IsCompleted } }
        public string Instance { get { return Account.Instance } }
    }

    public List<Job> Running = new List<Job>;

    public void AddJob(Account a, IAsyncResult result, Delegate del)
    {
        var j = new Job { Account = a, Result = result, Delegate = del };
        Running.Add(j);
    }

    public void RemoveJob(Job job)
    {
        Running.Remove(job);
    }

public bool IsInstanceRunning(string instance)
{
    return (Running.Count(x => x.Instance == instance) > 0);
}
}

这些备份作业将通过 BeginInvoke()/EndInvoke() 异步发生。调用代码(简化)看起来像这样:

public void BackupAccounts(IEnumerable<Account> accounts, int maxconcurrent = 4)
{
    // local copy
    List<Accounts> myaccounts = accounts.ToList();
    var jobs  = new JobTracker();

    while (myaccounts.Count > 0) 
    {
        // check our running jobs
        foreach (var job in jobs.Running)
        {
            if (job.IsCompleted)
            {
// PROBLEM LINE:
                job.Delegate.EndInvoke();
                jobs.RemoveJob(job);

            }
        }

        // more jobs!
        while (jobs.Count < maxconcurrent)
        {
            int i = 0;
            Account account = null;

            // choose the next account on a free instance
            while (int < accounts.Count)
            {
                account = accounts[i];
                // instance in use?
                if (jobs.InstanceIsRunning(account.Instance))
                {
                    i += 1;
                    continue;
                }
                else
                {
                    // start the job
                    accounts.RemoveAt(i);
                    BackupDelegate del = new BackupDelegate(BackupAccount, account);
                    IAsyncResult result = del.BeginInvoke();
                    jobs.AddJob(account, result, del);
                }
            }
        }

        // we're all full up, give it some time to work
        Thread.Sleep(2000);
    }
}

PS - 我知道这段代码可以大大简化。这是第一个可以正常工作的迭代——我只是不明白为什么 VS 不喜欢它。

Why is Visual Studio 2010 telling me "'System.Delegate' does not contain a definition for 'EndInvoke'" when I call job.Delegate.EndInvoke()? How do I fix it? Note that it likes BeginInvoke() just fine, and doesn't complain if I add EndInvoke() immediately after BeginInvoke() (thought hat doesn't accomplish what I want).

I have a little JobTracker class for tracking backup jobs:

public class JobTracker 
{
    private class Job
    {
        public Account Account { get; set; }
        public IAsyncResult Result { get; set; }
        public Delegate Delegate { get; set; }
        public bool IsCompleted { get { return result.IsCompleted } }
        public string Instance { get { return Account.Instance } }
    }

    public List<Job> Running = new List<Job>;

    public void AddJob(Account a, IAsyncResult result, Delegate del)
    {
        var j = new Job { Account = a, Result = result, Delegate = del };
        Running.Add(j);
    }

    public void RemoveJob(Job job)
    {
        Running.Remove(job);
    }

public bool IsInstanceRunning(string instance)
{
    return (Running.Count(x => x.Instance == instance) > 0);
}
}

These backup jobs will happen asynchronously via BeginInvoke()/EndInvoke(). The calling code (simplified) looks something like this:

public void BackupAccounts(IEnumerable<Account> accounts, int maxconcurrent = 4)
{
    // local copy
    List<Accounts> myaccounts = accounts.ToList();
    var jobs  = new JobTracker();

    while (myaccounts.Count > 0) 
    {
        // check our running jobs
        foreach (var job in jobs.Running)
        {
            if (job.IsCompleted)
            {
// PROBLEM LINE:
                job.Delegate.EndInvoke();
                jobs.RemoveJob(job);

            }
        }

        // more jobs!
        while (jobs.Count < maxconcurrent)
        {
            int i = 0;
            Account account = null;

            // choose the next account on a free instance
            while (int < accounts.Count)
            {
                account = accounts[i];
                // instance in use?
                if (jobs.InstanceIsRunning(account.Instance))
                {
                    i += 1;
                    continue;
                }
                else
                {
                    // start the job
                    accounts.RemoveAt(i);
                    BackupDelegate del = new BackupDelegate(BackupAccount, account);
                    IAsyncResult result = del.BeginInvoke();
                    jobs.AddJob(account, result, del);
                }
            }
        }

        // we're all full up, give it some time to work
        Thread.Sleep(2000);
    }
}

PS - I know this code can be greatly simplified. It's a first, get-it-working iteration -- I just can't figure out why VS doesn't like it.

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

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

发布评论

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

评论(2

油饼 2024-12-28 03:49:20

当您调用 BeginInvoke 时,您是在 Delegate特定子类上调用它。当您调用 EndInvoke 时,您试图在 System.Delegate 本身上调用它,这是行不通的。每个子类都声明自己的 Invoke/BeginInvoke/EndInvoke 方法集 - 它必须这样做,因为方法的签名根据不同的情况而变化您正在谈论的确切委托类型的签名。如果您查看 System.Delegate 的文档 你在那里找不到任何这些方法。

目前尚不清楚您的代码试图实现什么目的,但如果您想调用 EndInvoke,则需要将 Job.Delegate 设置为特定的委托类型。

When you call BeginInvoke, you're calling it on a specific subclass of Delegate. When you call EndInvoke, you're trying to call it on System.Delegate itself, which won't work. Each subclass declares its own Invoke/BeginInvoke/EndInvoke set of methods - which it has to, given that the signatures of the methods varies according to the signature of the exact delegate type you're talking about. If you look at the documentation for System.Delegate you won't find any of those methods there.

It's not really clear what your code is trying to achieve, but if you want to call EndInvoke, you'll need to make Job.Delegate a specific delegate type.

凡尘雨 2024-12-28 03:49:20

因为 Delegate 上不存在 EndInvoke。相反,您应该让 Job 类保存对 BackupDelegate 的引用。

Because EndInvoke doesn't exist on Delegate. Instead you should have your Job class hold a reference to a BackupDelegate.

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