簡體   English   中英

等待異步方法從單獨的方法完成

[英]Wait for an Async method to finish from a separate method

使用PostSharp使用AOP Logging包裝WCF服務調用OnMethodBoundaryAspectOnEntryOnExit方法。

處理:
調用OnEntry()DateTime表示調用的開始存儲在屬性中,並且在該任務繼續時方法結束之前啟動異步任務。

此任務格式化有關日志記錄的服務調用的一些信息,可能需要一些時間。 這些值作為屬性存儲在此類中以進行日志記錄。

OnExit() ,另一個DateTime信號表示存儲調用結束。 此時,我需要確保在OnEntry()方法中啟動的Task已完成,並且所有屬性都已准備好記錄到數據庫中。

問題是如何確保在OnEntry()啟動的任務完成以便在OnExit() 我考慮過設置一個布爾值, while(false) {Thread.Sleep(100);}然后在為true時結束,但由於某種原因這感覺不對。

以下是我目前為此設置的代碼。

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 = ...;
    }
}

編輯:好的,我想我誤解了你。

基本上,你需要記住你已經啟動的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
    }
}

就個人而言,我實際上只是在任務中設置字段 - 我將任務作為包含日志記錄參數的TTask<T> 然后,您可以將屬性中的唯一字段作為任務,並具有:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM