为什么 Visual Studio 2010 告诉我“System.Delegate”?不包含“EndInvoke”的定义?
当我调用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当您调用
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 ofDelegate
. When you callEndInvoke
, you're trying to call it onSystem.Delegate
itself, which won't work. Each subclass declares its ownInvoke
/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 forSystem.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 makeJob.Delegate
a specific delegate type.因为
Delegate
上不存在EndInvoke
。相反,您应该让 Job 类保存对BackupDelegate
的引用。Because
EndInvoke
doesn't exist onDelegate
. Instead you should have your Job class hold a reference to aBackupDelegate
.