Condividi tramite


Sviluppo di un functoid cumulativo personalizzato

Utilizzare un functoid cumulativo personalizzato per eseguire operazioni di accumulo sui valori che si presentano più volte all'interno di un messaggio di istanza.

Quando si sviluppa un functoid cumulativo, è necessario implementare tre funzioni, corrispondenti alle azioni di inizializzazione, accumulo e recupero necessarie affinché la mappa sia in grado di eseguire l'accumulo. Prima di esaminare queste funzioni, è importante illustrare la protezione dai thread.

Scrittura di un functoid thread-safe

Poiché in condizioni di utilizzo intensivo è possibile che più istanze di una mappa vengano eseguite contemporaneamente, è necessario che il codice del functoid sia thread-safe. Tra i punti da tenere presente vi sono i seguenti:

  • È necessario che lo stato statico sia thread-safe.

  • Non è necessario che lo stato dell'istanza sia sempre thread-safe.

  • Progettare tenendo in mente la possibilità di esecuzione in condizioni di utilizzo intensivo. Evitare i blocchi quando è possibile.

  • Se possibile, evitare la necessità di sincronizzazione.

    In BizTalk Server è disponibile un meccanismo semplice per ridurre la complessità della scrittura di un functoid cumulativo thread-safe. In tutte e tre le funzioni il primo parametro è identico, ovvero un valore di indice integer. Quando in BizTalk Server viene chiamata la funzione di inizializzazione, viene assegnato un numero univoco al valore di indice. È possibile utilizzare questo valore come indice in una matrice contenente valori di accumulo, come illustrato nel seguente codice:

private HashTable cumulativeArray = new HashTable();  
…  
// Initialization function  
public string InitCumulativeMultiply(int index)  
{  
    cumulativeArray[index] = 1.0;  
    return string.Empty;  
}  

In questo esempio viene utilizzato un oggetto HashTable anziché ArrayList in quanto la funzione di inizializzazione potrebbe non essere chiamata con valori di indice in sequenza.

Implementazione delle tre funzioni cumulative

Sarà necessario implementare tre funzioni per ciascun functoid cumulativo personalizzato che si sviluppa. Nella tabella riportata di seguito sono riepilogati funzioni e metodi che è necessario chiamare nel costruttore per poterli impostare. Tutte le funzioni restituiscono valori stringa.

Nota

È possibile assegnare alle funzioni il nome più adatto desiderato ma ogni funzione deve avere il numero e il tipo di argomenti specificato.

Scopo della funzione Argomenti Impostazione di un riferimento Impostazione script inline
Inizializzazione int index SetExternalFunctionName SetScriptBuffer con functionNumber = 0
Accumulo int index, string val, string scope SetExternalFunctionName2 SetScriptBuffer con functionNumber = 1
Recupero int index SetExternalFunctionName3 SetScriptBuffer con functionNumber = 2

Inizializzazione

L'inizializzazione consente di preparare i meccanismi da utilizzare per l'esecuzione dell'accumulo. È possibile inizializzare una matrice, reimpostare uno o più valori o caricare altre risorse in base alle esigenze. Il valore restituito della stringa non viene utilizzato.

Accumulo

Consiste nell'operazione di accumulo appropriata per il functoid. Vengono passati i seguenti tre parametri:

  • Index. Valore integer che rappresenta un'istanza di mappa. È possibile che vengano eseguite più istanze di mappa contemporaneamente.

  • Val. Stringa contenente il valore da accumulare. A meno che non si scriva un functoid cumulativo di stringa, è un valore numerico.

  • Ambito. Stringa contenente un numero che indica quale valore di elemento o attributo deve essere accumulato. I valori effettivi vengono determinati da un'implementazione.

    La discriminazione tra i valori da accumulare e i valori da ignorare viene stabilita dall'utente. È ad esempio possibile ignorare i valori non inferiori a 0 ma generare un'eccezione quando un valore non è numerico. BaseFunctoid fornisce due funzioni, IsDate e IsNumeric, per facilitare la convalida.

Nota

Se si usa IsDate o IsNumeric in uno script inline, assicurarsi di impostare RequiredGlobalHelperFunctions in modo che le funzioni vengano rese disponibili per lo script.

Il valore restituito della stringa non viene utilizzato.

Recupero

Quando termina l'iterazione di tutti i valori determinati dalle impostazioni del functoid nella mappa, viene richiesto il valore accumulato. La funzione get ha un argomento, Index, che è un valore intero che rappresenta un'istanza della mappa. È necessario che la funzione utilizzi il valore di indice per trovare e restituire il valore accumulato sotto forma di stringa.

Esempio

Nell'esempio seguente viene illustrato come creare un functoid personalizzato per l'esecuzione della moltiplicazione cumulativa. L'esempio si basa su un file di risorse che contiene tre risorse stringa e una risorsa bitmap di 16x16 pixel.

using System;  
using Microsoft.BizTalk.BaseFunctoids;  
using System.Reflection;  
using System.Text;  
using System.Collections;  
using System.Globalization;  
  
namespace Microsoft.Samples.BizTalk.CustomFunctoid  
{  
    public class CumulativeMultiplyFunctoid : BaseFunctoid  
    {  
        private ArrayList myCumulativeArray = new ArrayList();  
  
        public CumulativeMultiplyFunctoid() : base()  
        {  
            //ID for this functoid  
            ID = 6001;  
  
            // Resource assembly must be ProjectName.ResourceName if building with VS.Net  
            SetupResourceAssembly("Microsoft.Samples.BizTalk.CustomFunctoid.CustomFunctoidResources", Assembly.GetExecutingAssembly());  
  
            // Pass the resource ID names for functoid name, tooltip  
            // description and the 16x16 bitmap for the Map palette  
            SetName("IDS_CUMULATIVEMULTIPLYFUNCTOID_NAME");  
            SetTooltip("IDS_CUMULATIVEMULTIPLYFUNCTOID_TOOLTIP");  
            SetDescription("IDS_CUMULATIVEMULTIPLYFUNCTOID_DESCRIPTION");  
            SetBitmap("IDB_CUMULATIVEMULTIPLYFUNCTOID_BITMAP");  
  
            // Put this string handling function under the Cumulative  
            // Functoid tab in the Visual Studio toolbox for functoids  
            Category = FunctoidCategory.Cumulative;  
  
            // 2 required parameters, no optional parameters  
            SetMinParams(1);  
            SetMaxParams(2);  
  
            // Functoid accepts three inputs  
            AddInputConnectionType(ConnectionType.AllExceptRecord);  
            AddInputConnectionType((~ConnectionType.FunctoidCount) & (~ConnectionType.FunctoidIndex) & (~ConnectionType.FunctoidIteration) & (~ConnectionType.FunctoidCumulative) & (~ConnectionType.FunctoidLooping) & (~ConnectionType.Record));  
            AddInputConnectionType(ConnectionType.AllExceptRecord);  
  
            // Set the output connection type  
            OutputConnectionType = ConnectionType.AllExceptRecord;  
  
            // Set the Initialize, Cumulative and Get functions  
            SetExternalFunctionName(GetType().Assembly.FullName, "Microsoft.Samples.BizTalk.CustomFunctoid.CumulativeMultiplyFunctoid", "InitCumulativeMultiply");  
            SetExternalFunctionName2("AddToCumulativeMultiply");  
            SetExternalFunctionName3("GetCumulativeMultiply");  
        }  
  
        // Initialization function  
        public string InitCumulativeMultiply(int index)  
        {  
            if (index >= 0)  
            {  
                if (index >= myCumulativeArray.Count)  
                {  
                    myCumulativeArray.Add(1.0);  
                }  
                else  
                {  
                    myCumulativeArray[index] = 1.0;  
                }  
            }  
  
            return "";  
        }  
  
        // Cumulative function  
        public string AddToCumulativeMultiply(int index, string val, string reserved)  
        {  
            if (index < 0 || index >= myCumulativeArray.Count)  
            {  
                return "";  
            }  
  
            if (IsNumeric(val))  
            {  
                double dval = Convert.ToDouble(val, CultureInfo.InvariantCulture);  
                myCumulativeArray[index] = (double)(myCumulativeArray[index]) * dval;  
            }  
            return myCumulativeArray[index].ToString();  
        }  
  
        // Get Function  
        public string GetCumulativeMultiply(int index)  
        {  
            if (index < 0 || index >= myCumulativeArray.Count)  
            {  
                return "";  
            }  
  
            return myCumulativeArray[index].ToString();  
        }  
    }  

Vedere anche

Uso di BaseFunctoid
Sviluppo di un functoid inline personalizzato
Custom Functoid (esempio di BizTalk Server)