job.Delegate.EndInvoke()
を呼び出すと、「System.Delegate」に「EndInvoke」の定義が含まれていないというVisual Studio 2010が表示されるのはなぜですか?どうすれば修正できますか? BeginInvoke()
が好きで、BeginInvoke()
の直後にEndInvoke()
を追加しても文句を言っていないことに注意してください。"System.Delegate"に 'EndInvoke'の定義が含まれていないというVisual Studio 2010が表示されるのはなぜですか?
私は、バックアップジョブを追跡するために少し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がそれを好まない理由を理解できません。あなたがBeginInvoke
を呼び出すと
私は定義を含んでいませんでしたが、Delegateのサブクラスでこれを呼び出すことに気づくでしょう。 「//ジョブを開始する」の下で、BackupDelegateをインスタンス化し、JobTracker.AddJob()に送信します。私は誤解していますか? –
@ sh-beta:はい、あなたは '' Job.Delegate'のコンパイル時の型を見ています - それはちょうど 'Delegate'です。ですから、 'job.Delegate.EndInvoke()'を呼び出すと、 'Delegate'で宣言された' EndInvoke'メソッドを見つけようとしています。 'BackupDelegate'ではそうではありません。なぜなら、 'BeginInvoke'呼び出しはうまくコンパイルされます。なぜなら、' del'のコンパイル時の型は 'BackupDelegate'です。 –
ああ、私は今参照してください。ありがとう! –