के साथ ContextBoundObject मेरे पास एक प्रणाली है जो ContextBoundObject के साथ AOP का उपयोग करती है।Astec/Await
इसका उपयोग विधि कॉल को रोकने और फ़ंक्शन के पहले और बाद में कुछ संचालन करने के लिए किया जाता है। यह तब तक ठीक काम करता है जब तक कि मैं 'फ़ंक्शन को अवरुद्ध नहीं किया जाता' async।
मैं समझता हूँ कि सी # संकलक जैसे ही 'का इंतजार है' तो यह अवरोधन में जारी है पहुँच जाता है एक राज्य मशीन है, जो सिंक करने के लिए नियंत्रण रिटर्न में async तरीकों का पुनर्लेखन और कोड जो केवल क्रियान्वित किया जा करने के लिए है कार्यान्वित विधि के बाद।
मैं देख सकता हूं कि IMessageSink में "AsyncProcessMessage" है, लेकिन मुझे इसे आमंत्रित करने का कोई तरीका नहीं मिल रहा है, और मुझे यकीन नहीं है कि यह async/प्रतीक्षा परिदृश्य में काम करेगा या नहीं।
क्या Async/Await ContextBoundObject के साथ काम करने का कोई तरीका है? क्या एक और पहलू ओरिएंटेड प्रोग्रामिंग का उपयोग यहां एकमात्र विकल्प है?
नीचे दिए गए कोड नमूने में 'ऑडिट' विशेषता के साथ सजाए गए तरीके को ऑडिट किया गया है और ऑडिटफैक्ड में रखा गया है जो एक ContextBoundObject है। ऑडिट सिंक में सिंकप्रोसेस मैसेज विधि में विधि से पहले और बाद में निष्पादित किया जाना तर्क है।
[AuditBoundary]
public class AuditFacade : ContextBoundObject
{
[Audit]
public ResponseObject DoSomthing()
{
//Do something
return new ResponseObject();
}
/// <summary>
/// Async Method to be intercepted
/// </summary>
/// <returns></returns>
[Audit]
public async Task<ResponseObject> DoSomthingAysnc()
{
//Do something Async
await Task.Delay(10000);
return new ResponseObject();
}
}
[AttributeUsage(AttributeTargets.Method)]
public class AuditAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Class)]
public class AuditBoundaryAttribute : ContextAttribute
{
public AuditBoundaryAttribute()
: base("AuditBoundary" + Guid.NewGuid().ToString())
{
}
public override void GetPropertiesForNewContext(IConstructionCallMessage ctorMsg)
{
ctorMsg.ContextProperties.Add(new AuditProperty());
}
}
public class AuditProperty : IContextProperty, IContributeObjectSink
{
public string Name
{
get { return "AuditProperty"; }
}
public bool IsNewContextOK(Context newCtx)
{
var p = newCtx.GetProperty("AuditProperty") as AuditProperty;
if (p == null)
return false;
return true;
}
public void Freeze(Context newContext)
{
}
public IMessageSink GetObjectSink(MarshalByRefObject obj, IMessageSink nextSink)
{
return new AuditSink(nextSink);
}
}
public class AuditSink : IMessageSink
{
private IMessageSink nextSink;
public AuditSink(IMessageSink nextSink)
{
this.nextSink = nextSink;
}
public IMessage SyncProcessMessage(IMessage msg)
{
var message = msg as IMethodCallMessage;
IMethodReturnMessage returnMessage = null;
ResponseObject response;
//Some Pre Processing happens here
var newMessage = new MethodCallMessageWrapper(message);
//Invoke the Method to be Audited
returnMessage = nextSink.SyncProcessMessage(newMessage) as IMethodReturnMessage;
response = returnMessage.ReturnValue as ResponseObject;
//Some Post Processing happens here with the "response"
return returnMessage;
}
public IMessageSink NextSink
{
get { return this.nextSink; }
}
public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
{
return nextSink.AsyncProcessMessage(msg, replySink);
}
}