У нас есть этот общий сценарий, где у нас есть метод, который выполняет некоторое действие асинхронно и генерирует событие, когда это сделано.
Существуют времена, где мы хотим сделанный синхронно вместо этого, таким образом, у нас есть код, который выглядит подобным этому:
ManualResetEvent reset = new ManualResetEvent(false);
someobject.AsyncActionDone += (sender, args) => reset.Set();
someobject.PerformAsyncAction();
reset.WaitOne();
Существует ли способ записать вспомогательный метод сделать это? Я могу передать в Действии для выполнения, но я не уверен, как передать в чем-то, что позволяет вспомогательному методу знать, какое событие слушать, так как это не похоже, можно передать в EventHandler в качестве параметра.
Предпочтительно решение, которое не требует отражения
Кажется, существует некоторый беспорядок, это - образец того, на что похож класс someobject:
public class SomeClass
{
private ExternalServer someServerOverTheNetwork = new ExternalServer();
public event EventHandler AsyncActionDone;
public Data SomeData { get; set; }
public void PerformAsyncAction()
{
someServerOverTheNetwork.GetSomeData(OnDataRetrived);
}
public Data OnDataRetrived(Data someData)
{
AsyncActionDone(this, new DataEventArgs(someData));
}
}
Для меня я думаю, что лучший способ и самый простой способ - это создать временную таблицу, которая имеет все ваши связанные поля плюс дополнительное поле, которое является полем yeas/no.
, то вы будете использовать эту таблицу в качестве источника данных для непрерывной для. Для заполнения временной таблицы требуемыми данными используется функция onLoad.
Я думаю, что после этого легко сделать цикл для выбора, просто небольшой цикл, чтобы прочитать yeas/no поле из временной таблицы.
Надеюсь, это поможет
-121--2688874-При возникновении любой ошибки возникнут исключения. Единственные ошибки, о которых я могу думать, что это не сработает с параметром «пауза на исключениях», это синтаксические ошибки, которые происходят до того, как какой-либо из кодов будет выполнен, так что нет места для паузы в любом случае и ни один из кодов не будет запущен.
Очевидно, что Chrome не остановится на исключении, если он находится внутри блока try-catch. Он приостанавливается только на необдуманных исключениях. Я не знаю, путь это изменить.
Если нужно знать, в какой строке произошло исключение (тогда можно установить точку останова, если исключение воспроизводимо), объект Error
, заданный блоку catch, имеет свойство stack
, показывающее, где произошло исключение.
Я бы рассмотрел возможность реализации асинхронного образца проектирования в объектах, выполняющих асинхронную операцию.
public object Operation(object arg)
{
var ar = BeginOperation(arg, null, null);
return EndOperation(ar);
}
public IAsyncResult BeginOperation(object arg, AsyncCallback asyncCallback, object state)
{
AsyncResult asyncResult = new AsyncResult(asyncCallback, state);
// Lauch the asynchronous operation
return asyncResult;
}
private void LaunchOperation(AsyncResult asyncResult)
{
// Do something asynchronously and call OnOperationFinished when finished
}
private void OnOperationFinished(AsyncResult asyncResult, object result)
{
asyncResult.Complete(result);
}
public object EndOperation(IAsyncResult asyncResult)
{
AsyncResult ar = (AsyncResult)asyncResult;
return ar.EndInvoke();
}
С помощью этого образца можно выполнять несколько одновременных асинхронных операций над объектом.
Примечание: Вы можете легко найти реализацию общего класса AsyncResult в Интернете.
Правка:
При необходимости сохранения текущего проекта, если весь объект может иметь только одну асинхронную операцию, можно определить интерфейс IAsyncOperation и реализовать его во всем объекте.
public interface IAsyncOperation
{
event EventHandler AsyncActionDone;
void PerformAsyncAction();
}
Тогда вы могли бы иметь:
public static CallSynchronously(IAsyncOperation asyncOperation)
{
ManualResetEvent reset = new ManualResetEvent(false);
asyncOperation.AsyncActionDone += (sender, args) => reset.Set();
asyncOperation.PerformAsyncAction();
reset.WaitOne();
}
Если ваши объекты могут содержать несколько асинхронных операций, то без отражения я думаю, что нет пути достичь того, что вы хотите сделать, но вы все еще можете определить синхронную версию всех асинхронных операций, которая оборачивает ManityResetEvent.
public void PerformAction()
{
ManualResetEvent reset = new ManualResetEvent(false);
this.AsyncActionDone += (sender, args) => reset.Set();
this.PerformAsyncAction();
reset.WaitOne();
}
Если я уловил ваш дрейф, вы можете просто использовать делегаты следующим образом: создайте делегата для вызова функции, позвольте ему вызвать
public delegate string AsyncDelegate();
затем создайте такую прокси-функцию:
public static void ExecuteSync(AsyncDelegate func)
{
ManualResetEvent reset = new ManualResetEvent(false);
int threadId;
func.BeginInvoke((a)=>reset.Set(), null);
reset.WaitOne();
}
Вот и все, вы можете немного усложнить ее, добавив еще один делегат функции для запуска после завершения или что-то в этом роде ..
Наслаждайтесь!