C# 为什么VisualStudio2010告诉我';系统。代表';不包含';EndInvoke'&引用;?

C# 为什么VisualStudio2010告诉我';系统。代表';不包含';EndInvoke'&引用;?,c#,begininvoke,C#,Begininvoke,为什么Visual Studio 2010在调用job.Delegate.EndInvoke()时告诉我“'System.Delegate'不包含'EndInvoke'的定义”?我怎么修理它?请注意,它喜欢BeginInvoke()很好,如果我在BeginInvoke()之后立即添加EndInvoke()(虽然它不能实现我想要的) 我有一个用于跟踪备份作业的小JobTracker类: public class JobTracker { private class Job {

为什么Visual Studio 2010在调用
job.Delegate.EndInvoke()时告诉我“'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);
}
}
公共类工作跟踪器
{
私人职业
{
公共帐户{get;set;}
公共IAsyncResult结果{get;set;}
公共委托{get;set;}
public bool IsCompleted{get{return result.IsCompleted}
公共字符串实例{get{return Account.Instance}
}
公共列表运行=新列表;
public void AddJob(帐户a、IAsyncResult结果、委托del)
{
var j=新作业{Account=a,Result=Result,Delegate=del};
正在运行。添加(j);
}
公共作废移除作业(作业作业)
{
正在运行。删除(作业);
}
公共bool IsInstanceRunning(字符串实例)
{
返回(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);
    }
}
public void BackupAccounts(IEnumerable accounts,int-maxconcurrent=4)
{
//本地副本
List myaccounts=accounts.ToList();
var jobs=new JobTracker();
而(myaccounts.Count>0)
{
//检查我们正在运行的作业
foreach(jobs.Running中的var作业)
{
如果(作业已完成)
{
//问题线:
job.Delegate.EndInvoke();
jobs.RemoveJob(job);
}
}
//更多的工作!
while(jobs.Count

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

当您调用
BeginInvoke
时,您是在
Delegate
的特定子类上调用它。当您调用
EndInvoke
时,您试图在
System.Delegate
本身上调用它,这将不起作用。每个子类声明其自己的
Invoke
/
BeginInvoke
/
EndInvoke
方法集-鉴于方法的签名根据您所谈论的确切委托类型的签名而不同,因此必须声明该方法集。如果你看一下,你不会在那里找到这些方法中的任何一种


现在还不清楚您的代码试图实现什么,但是如果您想调用
EndInvoke
,您需要将
作业.委托
作为一种特定的委托类型。

因为
委托
上不存在
EndInvoke
。相反,您应该让您的作业类保存对
BackupDelegate

的引用,我没有包含该定义,但您会注意到,我确实将其称为Delegate的子类。在
//启动作业
下,我实例化BackupDelegate并将其发送到JobTracker.AddJob()。我误解了吗?@sh beta:是的,你是-看看
作业的编译时类型。Delegate
-它只是
Delegate
。因此,当您调用
job.Delegate.EndInvoke()
时,它试图查找在
Delegate
中声明的
EndInvoke
方法,而不是在
BackupDelegate
中声明的方法。这就是为什么
BeginInvoke
调用编译得很好,因为
del
的编译时类型是
BackupDelegate