Welcome Guest Search | Active Topics | Members | Log In | Register

Async Method Command Options · View
derek
Posted: Friday, April 25, 2008 12:36:14 PM
Rank: Advanced Member
Groups: Member

Joined: 4/24/2008
Posts: 6
Points: 18
Location: Scotland
Heres a command that takes a method and builds the delegates and Begin/End methods that allow it to be ran using the APM. Use the 'async' command anywhere inside the method.

C#
Code:

<?xml version="1.0"?>
<Commands xmlns="http://schemas.devprojects.net/AutoCode/v3.0">
  <Command name="MethodToAsync" priority="100">

    <CommandBehavior>
      <CommandLine shortcut="async" />
      <ActiveDocument extensions=".cs"/>
    </CommandBehavior>

    <CommandInfo>
      <LanguageCategory>CSharp</LanguageCategory>
      <Category>Members/Methods</Category>
      <Usage>
        <![CDATA[async]]>
      </Usage>
      <Description>Creates the delegates and Begin &amp; End methods needed for a method to support the APM.
      Only instance methods are supported.</Description>
      <Author>Derek Smyth</Author>
      <HelpUrl>http://www.dsmyth.net/wiki</HelpUrl>
    </CommandInfo>

    <CommandCode language="csharp">
    
      <Render>
     
        //string builder will build some code
        System.Text.StringBuilder buildr = new StringBuilder();
     
        //get the method that the current point is in
        CodeFunction cf = (CodeFunction) Selection.ActivePoint.get_CodeElement(vsCMElement.vsCMElementFunction);
        
        //if the method if function or sub
        if (cf.FunctionKind == vsCMFunction.vsCMFunctionFunction || cf.FunctionKind == vsCMFunction.vsCMFunctionSub)
        {    
            //get the code element
            CodeElement ce = GetCodeElement(CodeElementTypes.Function);
    
            TextPoint cp = ce.EndPoint;
            Selection.MoveToPoint(cp, false);
            
            buildr.Append("\r\n");
            buildr.Append("\r\n");
            
            buildr.Append("#region APM Methods for " + cf.Name);
            
            buildr.Append("\r\n");
            buildr.Append("\r\n");
            
            //declare the delegate prototype
            CodeTypeRef functionType = (CodeTypeRef)cf.Type;            
            buildr.Append("private delegate " + functionType.AsString + " Delegate" + cf.Name + "(");
            
            foreach(CodeParameter param in cf.Parameters)
            {
                CodeTypeRef paramType = (CodeTypeRef)param.Type;
                buildr.Append(paramType.AsString + " " + param.Name + ", ");
            }
            if (buildr.ToString().EndsWith(","))
            {
                buildr.Remove(buildr.Length - 1, 1);
            }
            buildr.Append(");");
            
            buildr.Append("\r\n");
            buildr.Append("private Delegate" + cf.Name + " " + cf.Name + "DelegateInstance;");
            
            buildr.Append("\r\n");
            buildr.Append("\r\n");
                    
            buildr.Append("public IAsyncResult Begin" + cf.Name + "(");
            
            foreach(CodeParameter param in cf.Parameters)
            {
                CodeTypeRef paramType = (CodeTypeRef)param.Type;
                buildr.Append(paramType.AsString + " " + param.Name + ", ");
            }
            
            buildr.Append("AsyncCallback DelegateCallback, ");
            buildr.Append("object DelegateAsyncState");
            buildr.Append(")");
            buildr.Append("\r\n");
            buildr.Append("{");
            buildr.Append("\r\n");
            buildr.Append("if(" + cf.Name + "DelegateInstance == null)");
            buildr.Append("\r\n");
            buildr.Append(cf.Name + "DelegateInstance = new Delegate" + cf.Name +"(" + cf.Name + ");");
            buildr.Append("\r\n");
            buildr.Append("return "+ cf.Name + "DelegateInstance.BeginInvoke(");

            foreach(CodeParameter param in cf.Parameters)
            {
                CodeTypeRef paramType = (CodeTypeRef)param.Type;
                buildr.Append(param.Name + ", ");
            }
        
            buildr.Append("DelegateCallback, ");
            buildr.Append("DelegateAsyncState");
            buildr.Append(");");
    
            buildr.Append("\r\n");
            buildr.Append("}");
            
            buildr.Append("\r\n");
            buildr.Append("\r\n");
            
            buildr.Append("public " + functionType.AsString + " End" + cf.Name + "(IAsyncResult result)");
            buildr.Append("\r\n");
            buildr.Append("{");
            buildr.Append("\r\n");
            
            if (functionType.AsString == "void")
                buildr.Append(cf.Name + "DelegateInstance.EndInvoke(result);");
            else            
                buildr.Append("return "+ cf.Name + "DelegateInstance.EndInvoke(result);");
            
            buildr.Append("\r\n");
            buildr.Append("}");
            
            buildr.Append("\r\n");
            buildr.Append("\r\n");        
            
            
            buildr.Append("#endregion");
        }
        

        Selection.Text = buildr.ToString();
                
      </Render>

      <SmartFormat>
        <Start codeElement="Document" codePoint="StartOfElement" />
        <End codeElement="Document" codePoint="EndOfElement" />
      </SmartFormat>
     
    </CommandCode>
  </Command>

</Commands>



VB.NET
Code:

<?xml version="1.0"?>
<Commands xmlns="http://schemas.devprojects.net/AutoCode/v3.0">
  <Command name="MethodToAsync" priority="100">

    <CommandBehavior>
      <CommandLine shortcut="async" />
      <ActiveDocument extensions=".vb"/>
    </CommandBehavior>

    <CommandInfo>
      <LanguageCategory>VB.NET</LanguageCategory>
      <Category>Members/Methods</Category>
      <Usage>
        <![CDATA[async]]>
      </Usage>
      <Description>Creates the delegates and Begin &amp; End methods needed for a method to support the APM.
      Only instance methods are supported.</Description>
      <Author>Derek Smyth</Author>
      <HelpUrl>http://www.dsmyth.net/wiki</HelpUrl>
    </CommandInfo>

    <CommandCode language="csharp">
    
      <Render>
     
        //string builder will build some code
        System.Text.StringBuilder buildr = new StringBuilder();
     
        //get the method that the current point is in
        CodeFunction cf = (CodeFunction) Selection.ActivePoint.get_CodeElement(vsCMElement.vsCMElementFunction);
        
        //get the code element
        CodeElement ce = GetCodeElement(CodeElementTypes.Function);
    
        TextPoint cp = ce.EndPoint;
        Selection.MoveToPoint(cp, false);
            
        buildr.Append("\r\n");
        buildr.Append("\r\n");
            
        buildr.Append("#Region \"APM Methods for " + cf.Name + "\"");
            
        buildr.Append("\r\n");
        buildr.Append("\r\n");    
        
        CodeTypeRef functionType = (CodeTypeRef)cf.Type;
        
        if (cf.FunctionKind == vsCMFunction.vsCMFunctionFunction)
        {
            //declare the delegate prototype; function            
            buildr.Append("Private Delegate Function " + cf.Name + "Delegate(");
            
            foreach(CodeParameter param in cf.Parameters)
            {
                CodeTypeRef paramType = (CodeTypeRef)param.Type;
                buildr.Append("ByVal " + param.Name + " As " + paramType.AsString + ", ");
                
            }
            buildr.Remove(buildr.Length - 2, 1);
            buildr.Append(") As " + functionType.AsString);
            
        }        
        else if(cf.FunctionKind == vsCMFunction.vsCMFunctionSub)
        {    
            //declare the delegate prototype; Sub            
            buildr.Append("Private Delegate Sub " + cf.Name + "Delegate(");
            
            foreach(CodeParameter param in cf.Parameters)
            {
                CodeTypeRef paramType = (CodeTypeRef)param.Type;
                buildr.Append("ByVal " + param.Name + " As " + paramType.AsString + ", ");
                
            }
            buildr.Remove(buildr.Length - 2, 1);
            buildr.Append(")");
        }


        buildr.Append("\r\n");
        buildr.Append("Private " + cf.Name + "DelegateInstance As New " + cf.Name + "Delegate(AddressOf " + cf.Name + ")");
            
        buildr.Append("\r\n");
        buildr.Append("\r\n");
                    
        buildr.Append("Public Function Begin" + cf.Name + "(");
            
        foreach(CodeParameter param in cf.Parameters)
        {
            CodeTypeRef paramType = (CodeTypeRef)param.Type;
            buildr.Append("ByVal " + param.Name + " As " + paramType.AsString + ", ");
        }
            
        buildr.Append("ByVal DelegateCallback As AsyncCallback, ");
        buildr.Append("ByVal DelegateAsyncState As Object");
        buildr.Append(") As IAsyncResult");
        buildr.Append("\r\n");    
        
        buildr.Append("Return "+ cf.Name + "DelegateInstance.BeginInvoke(");

        foreach(CodeParameter param in cf.Parameters)
        {
            CodeTypeRef paramType = (CodeTypeRef)param.Type;
            buildr.Append(param.Name + ", ");
        }
        
        buildr.Append("DelegateCallback, ");
        buildr.Append("DelegateAsyncState");
        buildr.Append(")");
    
        buildr.Append("\r\n");    
            
        buildr.Append("End Function");
        
        
            
        buildr.Append("\r\n");
        buildr.Append("\r\n");
        
        
        
        if (cf.FunctionKind == vsCMFunction.vsCMFunctionFunction)
        {
            buildr.Append("Public Function End" + cf.Name + "(ByVal result As IAsyncResult) As " + functionType.AsString);
            buildr.Append("\r\n");
            buildr.Append("Return "+ cf.Name + "DelegateInstance.EndInvoke(result)");
            buildr.Append("\r\n");
            buildr.Append("End Function");
            
        }        
        else if(cf.FunctionKind == vsCMFunction.vsCMFunctionSub)
        {    
            buildr.Append("Public Sub End" + cf.Name + "(ByVal result As IAsyncResult)");
            buildr.Append("\r\n");
            buildr.Append(cf.Name + "DelegateInstance.EndInvoke(result)");
            buildr.Append("\r\n");
            buildr.Append("End Sub");
        }
        
        
            
        buildr.Append("\r\n");
        buildr.Append("\r\n");        
    
        buildr.Append("#End Region");
        

        Selection.Text = buildr.ToString();
                
      </Render>

    </CommandCode>
  </Command>

</Commands>


Let me know if you have any problems with it.
Alvaro
Posted: Monday, April 28, 2008 11:56:23 AM
Rank: Administration
Groups: Administration

Joined: 3/16/2008
Posts: 22
Points: 72
Location: Spain
It works perfect! And it’s a very interesting one, not just because it shows how to access the CodeModel, but also because it shows how to create an async method. These are one of those patterns that take you a while to find when you need it.
I always forget exactly how to implement typical patterns as writing an event or how to serialize a class and need to do a search to remember, so having it done just executing a command is very time saving.

By the way, I took a look at your site http://www.dsmyth.net/wiki and found it a very interesting place for .net resources I have already bookmarked. Great work!

Thanks,

Alvaro
Users browsing this topic
Guest


Forum Jump
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

Powered by Yet Another Forum.net version 1.9.1.8 (NET v2.0) - 3/29/2008