Я недавно пытался реализовать модель асинхронного обратного вызова, так что, когда разработчики используют мою библиотеку, им не нужно беспокоиться о следующем:
if(control.InvokeRequried) { // invoke }
Эта часть кода, кажется, работает довольно хорошо, но сегодня я обнаружил кое-что немного странное, что, я думаю, я поставил диагноз, но хотел бы посмотреть, что думают другие с большим опытом, и способы, которыми я мог бы быть в состоянии решить.
Проблема, с которой я столкнулся, заключается в том, что мои сообщения по какой-то причине очень медленные, и, следовательно, они, похоже, немного забиты и продолжают работать после того, как я завершил свою работу. Пример краткого кода:
// called by user
WorkerEventHandler workerDelegate = new WorkerEventHandler(CalcAsync);
workerDelegate.BeginInvoke(p, asyncOp, null, null);
CalcAsync(P p, AsyncOperation asyncOp)
{
Calculate();
asyncOp.PostOperationCompleted(new AsyncCompletedEventArgs(null, false,
asyncOp.UserSuppliedState);
}
Calculate()
{
DoStuff() // updates the progress as it goes
this.UpdateStatus("Done"); // marks us as done
this.UpdateProgress(pId, 100); // increase progress to max
}
При переходе я получаю повторные звонки на UpdateProgress , который вызывается из опубликованных событий, однако, похоже, что они не в состоянии следить и все еще публикуются. Они обрабатываются так:
// initalized with
// onProgressUpdatedDelegate = new SendOrPostCallback(UpdateProgress);
private SendOrPostCallback onProgressUpdatedDelegate;
public void UpdateProgress(Guid pId, ProgressEventArgs e)
{
AsyncOperation asyncOp = GetAsyncOperation(pId);
if (asyncOp != null)
{
asyncOp.Post(this.onProgressUpdatedDelegate, e);
}
else
{
UpdateProgress(this, e);
}
}
private void UpdateProgress(object state)
{
ProgressEventArgs e = state as ProgressEventArgs;
UpdateProgress(this, e); // does the actual triggering of the EventHandler
}
Если это актуально, все эти события записываются на консоль. Но мне кажется, что мой прогресс сводится только к более длительным операциям, которые, похоже, совпадают с результатами, которые я вижу в своем тестовом приложении WPF.
Это говорит о том, что сообщение просто медленное? Я полагаю, что мне действительно хотелось бы, чтобы каждый раз, когда я звонил UpdateProgress через сообщение, я хочу удалить все существующие сообщения в очереди, если это так. Но я не уверен, что это возможно? Если это так, возможно ли очистить только эти события, так как я не хочу затем чистить мое событие UpdateStatus случайно ...
Редактировать
Некоторые из отсутствующих методов, если это облегчает.
public void UpdateProgress(Guid pId, ProgressEventArgs e)
{
AsyncOperation asyncOp = GetAsyncOperation(pId);
if (asyncOp != null)
{
asyncOp.Post(this.onProgressUpdatedDelegate, e);
}
else
{
UpdateProgress(this, e);
}
}
private void UpdateProgress(object sender, ProgressEventArgs e)
{
ProgressChangedEventHandler handler;
lock (progressUpdateEventLock)
{
handler = progressUpdateEvent;
}
if (handler != null)
handler(sender, e);
}