2014-01-30 5 views
0

Использование PostSharp для обертывания вызова службы WCF с помощью АОП с использованием методов OnEntry и OnExit для OnMethodBoundaryAspect.Подождите, пока метод Async закончит по отдельному методу

Процесс:
OnEntry() это называют, DateTime сигнализации о начале вызова хранится в свойстве и асинхронная задача, запускается перед тем, способ завершается в то время как целевая продолжается.

Эта задача форматирует некоторую информацию о вызове службы для ведения журнала и может занять некоторое время. Эти значения сохраняются в качестве свойств этого класса для ведения журнала.

OnExit() называется, еще DateTime сигнализация окончания вызова сохраняется. На этом этапе мне нужно убедиться, что Задача, запущенная в методе OnEntry(), завершена, и все свойства готовы к регистрации в базе данных.

Вопрос заключается в том, как я могу убедиться, что задачи началась в OnEntry() завершена для использования в OnExit()? Я подумал о создании логического, while(false) {Thread.Sleep(100);}, а затем закончить, когда это правда, но по какой-то причине это не кажется правильным.

Ниже приведен код, который я сейчас установил для этого.

class LogMethodCallAttribute : OnMethodBoundaryAspect 
{ 
    Int32 userId; 
    String methodCall; 
    String ip; 
    DateTime entryTime; 
    DateTime exitTime; 

    /// Performs tasks on a Method before its execution. 
    public override void OnEntry(MethodExecutionArgs args) 
    { 
     // Set OnEntry Time 
     entryTime = DateTime.Now; 

     if (ConfigurationManager.AppSettings["AOPLoggingEnabled"] == "1") 
     { 
      MessageProperties prop = OperationContext.Current.IncomingMessageProperties; 
      // Queue the logging to run on the ThreadPool so the service can finish the request. 
      Task.Factory.StartNew(() => SetUpLog(args, prop));    
     } 
    } 

    public override void OnExit(MethodExecutionArgs args) 
    { 
     // Set OnExit Time 
     exitTime = DateTime.Now; 

     // Need to make sure the Task running SetUpLog is complete and all props set. 

     // Log the details of this method call. 
     Logs.LogWebServiceCall(userId, methodName, ip, entryTime, exitTime); 
    } 

    // Format details for logging. 
    private void SetUpLog(MethodExecutionArgs args, MessageProperties prop) 
    { 
     // Retrieve all the required data and do any formatting. 
     userId = ...; 
     methodCall = ...; 
     ip = ...; 
    } 
} 
+3

магазин задача вернулся из 'Task.Factory.StartNew' в vriable и' Wait' его в OnExit. –

ответ

2

EDIT: Хорошо, думаю, я вас неправильно понял.

В принципе, вы должны помнить Task, что вы начали, а затем вы можете просто позвонить Wait() подождать, пока он не закончил:

class LogMethodCallAttribute : OnMethodBoundaryAspect 
{ 
    Task task; 
    ... as before ... 

    public override void OnEntry(MethodExecutionArgs args) 
    { 
     ... 
     task = Task.Factory.StartNew(...); 
    } 

    public override void OnExit(MethodExecutionArgs args) 
    { 
     exitTime = DateTime.Now; 
     // Wait for the task to have completed... 
     task.Wait(); 
     // Now you can use the fields 
    } 
} 

Лично я бы на самом деле не просто установить поля задача - я поставил бы задачу Task<T> для некоторого T, который содержит параметры ведения журнала. После этого вы можете сделать только поле в атрибуте задачи и иметь:

var loggingParameters = task.Result; 
... use the logging parameters 
+0

Услуга сама по себе может занять некоторое время. Первоначально мы не интересовались временем начала и окончания и просто асинхронно запускали журнал регистрации и забыли об этом. При этом новом требовании вызов службы займет больше 99,99% времени, и все данные должны ждать в полях, готовых к работе. Если я правильно понимаю, вы говорите, что способ, которым он должен быть, - это метод создания Задачи, завершающийся перед самой Задачей, которая является видом противоположности того, что я пытаюсь сделать? – WebDevNewbie

+0

@WebDevNewbie: Я подозреваю, что неправильно понял ваши требования. Будет редактировать мой пост. –

+0

Большое спасибо, что дополнительное предложение об использовании Task действительно помогло :) – WebDevNewbie

Смежные вопросы