Freigeben über


Exemplarische Vorgehensweise: Erstellen, Debuggen und Bereitstellen einer Anwendung mit Visual F#

Diese exemplarische Vorgehensweise bringt Ihnen die Verwendung von F# in Visual Studio mit .NET Framework 4.5 näher.

In dieser exemplarischen Vorgehensweise erfahren Sie anhand einer historischen Analyse von Zinssatzdaten des US-Finanzministeriums, wie Sie mithilfe von Visual Studio F#-Anwendungen erstellen. Wir beginnen mit einigen einfachen Datenanalysen, die im interaktiven Fenster von F# durchgeführt werden. Anschließend beschäftigen wir uns mit dem Schreiben und Testen von Code zur Datenanalyse. Schließlich fügen wir ein C#-Front-End hinzu, mit dem die Integration des F#-Codes in andere .NET-Sprachen vorgenommen wird.

Vorbereitungsmaßnahmen

Zum Durchführen dieser exemplarischen Vorgehensweise benötigen Sie die folgenden Komponenten:

  • Visual Studio

Hinweis

Auf Ihrem Computer werden möglicherweise andere Namen oder Speicherorte für die Benutzeroberflächenelemente von Visual Studio angezeigt als die in den folgenden Anweisungen aufgeführten. Diese Elemente sind von der jeweiligen Visual Studio-Version und den verwendeten Einstellungen abhängig. Weitere Informationen finden Sie unter Anpassen der Entwicklungseinstellungen in Visual Studio.

So erstellen Sie ein F#-Skript

  1. Erstellen Sie zunächst ein F#-Skript. Zeigen Sie im Menü Datei auf Neu, und klicken Sie auf Datei. Wählen Sie Skript im Dialogfeld Neue Datei (in der Kategorie Allgemein unter der Vorlagenliste Installiert) und dann F#-Skriptdatei. Klicken Sie auf Öffnen, um die Datei zu erstellen, und speichern Sie die Datei unter der Bezeichnung RateAnalysis.fsx.

  2. Greifen Sie mithilfe von .NET- und F#-APIs auf Daten von der Website der amerikanischen Zentralbank zu. Geben Sie den folgenden Code ein.

    open System.Net
    open System.IO
    
    let url = sprintf "http://www.federalreserve.gov/datadownload/Output.aspx?rel=H15&series=bcb44e57fb57efbe90002369321bfb3f&lastObs=&from=&to=&filetype=csv&label=include&layout=seriescolumn" 
    let req = WebRequest.Create(url, Timeout = 10000000)
    let resp = req.GetResponse()
    let stream = resp.GetResponseStream()
    let reader = new StreamReader(stream)
    let csv = reader.ReadToEnd()
    

    Beachten Sie Folgendes:

    • Zeichenfolgen und Schlüsselwörter werden farbig hervorgehoben.

    • Nach dem Eingeben der einzelnen Punkte (.) werden Vervollständigungslisten angezeigt.

    • Sie können Methodennamen und andere Bezeichner von Visual Studio vervollständigen lassen. Verwenden Sie hierzu in der Mitte eines Bezeichners die Tastenkombinationen STRG+LEERTASTE oder STRG+J. Bei der Verwendung von STRG+J wird eine Vervollständigungsliste angezeigt.

    • Zeigen Sie mit dem Cursor auf einen Bezeichner im Code, um eine QuickInfo mit Informationen zu diesem Bezeichner anzuzeigen.

    • Befindet sich der Cursor über WebRequest und drücken Sie dann F1, wird die entsprechende Dokumentation angezeigt.

    • Befindet sich der Cursor über let und drücken Sie dann F1, wird die entsprechende Dokumentation angezeigt.

    • Auf Typen und Namespaces von mscorlib.dll, System.dll und System.Windows.Forms.dll wird standardmäßig verwiesen.

    • Der hier festgelegte Timeout-Wert ist eine Eigenschaft, kein Konstruktorargument. Mit F# können Sie Eigenschaftswerte auf diese Weise festlegen.

    • Wenn Sie die Beispiel-URL in einen Browser kopieren, erhalten Sie eine Reihe von durch Trennzeichen getrennte Daten- und Zinssatzwerte, die von der amerikanischen Zentralbank veröffentlicht wurden.

  3. Jetzt wird der Code mit F# Interactive ausgeführt. Markieren Sie mit der Maus oder der Tastenkombination STRG+A den gesamten Code, klicken Sie anschließend mit der rechten Maustaste, und wählen Sie Interaktiv ausführen aus. Alternativ können Sie die Tastenkombination ALT+EINGABETASTE verwenden.

    • Das Fenster "F# Interactive" wird geöffnet, sofern es nicht bereits angezeigt wurde.

    • Der Code wird erfolgreich ausgeführt.

    • Im Fenster "F# Interactive" wird Folgendes angezeigt.

      val url : string =
        "http://www.federalreserve.gov/datadownload/Output.aspx?rel=H1"+[107 chars]
      val req : System.Net.WebRequest
      val resp : System.Net.WebResponse
      val stream : System.IO.Stream
      val reader : System.IO.StreamReader
      
      val csv : string =
        ""Series Description","Market yield on U.S. Treasury securities"+[224219 chars]
      
      >
      
  4. Überprüfen Sie anschließend die Daten mit F# Interactive. Geben Sie in die Eingabeaufforderung von F# Interactive csv;; ein, und drücken Sie die EINGABETASTE. Geben Sie csv.Length ein;;, und drücken Sie die EINGABETASTE. Beachten Sie Folgendes:

    • Die Daten sind aktuell.

    • F# Interactive zeigt den Wert der Zeichenfolge csv und seine Länge an.

      07/10/2009, 3.32
      07/13/2009, 3.38
      07/14/2009, 3.50
      07/15/2009, 3.63
      "
      > csv.Length;;
      val it : int = 224513
      
    • Die folgende Abbildung zeigt das F# Interactive-Fenster.

      F# Interactive-Fenster

      F# Interactive-Fenster

  5. Jetzt erstellen wir F#-Code zur Analyse von CSV (durch Trennzeichen getrennte Werte)-Daten. Eine CSV-Datei wird so genannt, da die in ihr enthaltenen Werte durch Trennzeichen getrennt sind. Fügen Sie im Code-Editor folgenden Code hinzu: Fügen Sie außerdem open System.Globalization am Anfang der Datei hinzu. Wählen Sie beim Hinzufügen der einzelnen Zeilen den Code aus, der in diesem Abschnitt bis zur Zeile hinzugefügt wurde, und drücken Sie ALT+EINGABE, um die partiellen Ergebnisse anzuzeigen. Beachten Sie Folgendes:

    • Nach der Eingabe eines Punkts erhalten Sie selbst in der Mitte von komplexen geschachtelten Ausdrücken von IntelliSense hilfreiche Informationen.

    • Ist der Code unvollständig (oder falsch), wird durch rote wellenförmige Unterstreichung angezeigt, dass Syntaktik- und Semantikfehler im Code auftreten.

    • Pipelines werden mit dem Pipeoperator (|>) erstellt. Der Pipeoperator verwendet den Rückgabewert eines Ausdrucks als Argument für die Funktion auf der nächsten Zeile. Pipelines und F# Interactive ermöglichen die einfache partielle Ausführung von Datenverarbeitungscodes.

    let interest = 
        csv.Split([|'\n'|])
        |> Seq.skip 8
        |> Seq.map (fun line -> line.Trim())
        |> Seq.filter (fun line -> not (line.EndsWith("ND")))
        |> Seq.filter (fun line -> not (line.Length = 0))
        |> Seq.map (fun line -> line.Split([|','|]))
        |> Seq.map ( fun values ->
            System.DateTime.Parse(values.[0], CultureInfo.CreateSpecificCulture("en-US")),
            float values.[1])
    
  6. Jetzt erhält diese Funktionalität einen Namen. Entfernen Sie die Serien-ID bcb44e57fb57efbe90002369321bfb3f aus der Definition von url, und ersetzen Sie den Wert durch %s, um das Zeichenfolgenliteral in eine Formatzeichenfolge umzuwandeln. Fügen Sie nach der Formatzeichenfolge seriesID ein. Markieren Sie den gesamten Code außer den geöffneten Direktiven, und drücken Sie dann die Taste TAB. Fügen Sie über dem eingezogenen Codeblock die folgenden Codezeilen hinzu.

    let loadRates maturity =
        // The following tuples associate various maturity durations, in years, 
        // with codes defined for treasury bills by the Federal Reserve. 
        let maturitiesMap = Map.ofList [(1, "e30653a4b627e9d1f2490a0277d9f1ac")
                                        (2, "c66ea77a2e8f0919c5133c7633065908")
                                        (5, "fbb02942bfdbff31a479e98bcbe26388")
                                        (10, "bcb44e57fb57efbe90002369321bfb3f")
                                        (20, "a1ebeb6e84ca6389772dd054dc980191")]
        let seriesID = Map.find maturity maturitiesMap
    

    Fügen Sie am Ende des eingezogenen Blocks interest hinzu. Beachten Sie Folgendes:

    Der Code sieht nun folgendermaßen aus:

    open System.Net
    open System.IO
    
    let loadRates maturity =
        // The following tuples associate various maturity durations, in years, 
        // with codes defined for treasury bills by the Federal Reserve. 
        let maturitiesMap = Map.ofList [(1, "e30653a4b627e9d1f2490a0277d9f1ac")
                                        (2, "c66ea77a2e8f0919c5133c7633065908")
                                        (5, "fbb02942bfdbff31a479e98bcbe26388")
                                        (10, "bcb44e57fb57efbe90002369321bfb3f")
                                        (20, "a1ebeb6e84ca6389772dd054dc980191")]
        let seriesID = Map.find maturity maturitiesMap
        let url = sprintf "http://www.federalreserve.gov/datadownload/Output.aspx?rel=H15&series=%s&lastObs=&from=&to=&filetype=csv&label=include&layout=seriescolumn" seriesID
        let req = WebRequest.Create(url, Timeout = 10000000)
        let resp = req.GetResponse()
        let stream = resp.GetResponseStream()
        let reader = new StreamReader(stream)
        let csv = reader.ReadToEnd()
    
    
        let interest = 
            csv.Split([|'\n'|])
            |> Seq.skip 8
            |> Seq.map (fun line -> line.Trim())
            |> Seq.filter (fun line -> not (line.EndsWith("ND")))
            |> Seq.filter (fun line -> not (line.Length = 0))
            |> Seq.map (fun line -> line.Split([|','|]))
            |> Seq.map ( fun values ->
                System.DateTime.Parse(values.[0], CultureInfo.CreateSpecificCulture("en-US")),
                float values.[1])
        interest
    
  7. Jetzt verwenden wir diese Funktionalität für neue Eingaben. Wählen Sie den ganzen Code aus, und drücken Sie ALT+EINGABE, um ihn mit F# Interactive auszuführen. Rufen Sie über die F# Interactive-Eingabeaufforderung die neue loadRates-Funktion für andere Reiferaten auf: 1, 2 und 5 (in Jahren). Beachten Sie Folgendes:

    • Vorherige Definitionen gehen in F# Interactive nicht verloren, aber neue Definitionen sind verfügbar.

    • Komplexe strukturierte Daten werden mithilfe einer speziellen Druckfunktion gerendert.

So entwickeln Sie eine Komponente mit F#

  • Erstellen Sie ein Bibliotheksprojekt, um die erstellte Funktion bereitzustellen. Zeigen Sie im Menü Datei auf Neu, und klicken Sie dann auf Projekt. Wählen Sie im Dialogfeld Neues Projekt in der Liste Installierte Vorlagen die Option Visual F# und anschließend F#-Bibliothek aus, um ein neues Bibliotheksprojekt zu erstellen. Geben Sie dem Projekt den Namen RateAnalysis. Kopieren Sie den Code, den Sie zuvor aus RateAnalysis.fsx erstellt haben, und fügen Sie ihn in Library1.fs ein. Fügen Sie eine Moduldeklaration am Anfang der Datei hinzu: module RateLoader. Benennen Sie im Projektmappen-Explorer Library1.fs um in RateLoader.fs, und speichern Sie die Datei. Beachten Sie Folgendes:

    • Die standardmäßige F#-Bibliothek-Vorlage stellt eine Codedatei mit der Erweiterung .fs und ein Skript mit der Erweiterung .fsx bereit. Sie können die Skriptdatei zum interaktiven Testen des Bibliothekscodes verwenden.
  1. Jetzt erstellen wir eine F#-Klasse, die die gewünschte Funktionalität bereitstellt. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, zeigen Sie auf Hinzufügen und klicken Sie dann auf Neues Element. Wählen Sie im Dialogfeld Neues Element hinzufügen die Option für die F#-Quelldatei aus. Benennen Sie die Datei Analyzer.fs. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf Script.fsx, und klicken Sie anschließend auf Nach unten. Alternativ können Sie die Tastenkombination ALT+NACH-UNTEN verwenden. Fügen Sie folgenden Code in Analyzer.fs ein:

    module RateAnalysis.Analyzer
    
    open RateLoader
    
    /// Provides analysis of historical interest rate data. 
    type Analyzer(ratesAndDates) = 
        let rates = 
            ratesAndDates
            |> Seq.map snd
    
        /// Construct Analyzer objects for each maturity category. 
        static member GetAnalyzers(maturities) = 
            maturities
            |> Seq.map loadRates
            |> Seq.map (fun ratesAndDates -> new Analyzer(ratesAndDates))
    
        member sa.Min =
            let date, minRate = (Seq.minBy (fun (_, rate) -> rate) ratesAndDates)
            (minRate, date.ToString("d"))
    
        member sa.Max = 
            let date, maxRate = (Seq.maxBy (fun (_, rate) -> rate) ratesAndDates)
            (maxRate, date.ToString("d"))
    
        member sa.Current =
            rates |> List.ofSeq |> List.rev |> List.head 
    

    Beachten Sie Folgendes:

    • F# unterstützt objektorientierte Programmierungskonzepte. Weitere Informationen finden Sie in Klassen (F#), Vererbung (F#) und in anderen relevanten Themen der F#-Sprachreferenz.
  2. Drücken Sie STRG+UMSCHALT+B oder F6, um das Projekt zu erstellen. Beachten Sie Folgendes:

    • Das Projekt wird erfolgreich erstellt.

    • Im Fehlerlistenfenster werden keine Fehler angezeigt.

    • Das Ausgabeverzeichnis enthält .dll, .pdb- und .xml-Dateien.

    • Im Ausgabefenster wird Folgendes angezeigt:

      ------ Build started: Project: RateAnalysis, Configuration: Debug Any CPU ------
          C:\Program Files (x86)\Microsoft F#\v4.0\fsc.exe -o:obj\Debug\RateAnalysis.exe -g --debug:full --noframework --define:DEBUG --define:TRACE --optimize- --tailcalls- -r:"C:\Program Files (x86)\Microsoft F#\v4.0\FSharp.Core.dll" -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll" -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Core.dll" -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.dll" --target:exe --warn:3 --warnaserror:76 --vserrors --utf8output --fullpaths --flaterrors Program.fs RateLoader.fs ValueAnalyzer.fs 
          RateAnalysis -> C:\Users\ghogen\Documents\Visual Studio 10\Projects\RateAnalysis\RateAnalysis\bin\Debug\RateAnalysis.exe
      ========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ==========
      
  3. Öffnen Sie zum Hinzufügen einer C#-Clientanwendung das Kontextmenü für den Projektmappenknoten, wählen Sie Hinzufügen aus, und wählen Sie dann Neues Projekt. Wählen Sie im Dialogfeld Neues Projekt hinzufügen in der Liste Installierte Vorlagen die Option Visual C# aus, und klicken Sie anschließend auf Konsolenanwendung. Möglicherweise muss der Knoten Andere Sprachen erweitert werden. Nennen Sie das Projekt CSharpDriver, und klicken Sie dann auf die Schaltfläche OK. Öffnen Sie das Kontextmenü für den Knoten Verweise dieses Projekts, und wählen Sie dann Verweis hinzufügen aus. Wählen Sie den Knoten Projektmappe und dann den Knoten Projekte. Aktivieren Sie das Kontrollkästchen neben dem RateAnalysis-Projekt, und wählen Sie dann die Schaltfläche OK. Öffnen Sie das Kontextmenü für den Projektknoten CSharpDriver, und klicken Sie dann auf Als Startprojekt festlegen. Geben Sie den folgenden Code in den Text der Main-Methode der C#-Anwendung ein.

    var maturities = new[] { 1, 2, 5, 10 };
    var analyzers = RateAnalysis.Analyzer.Analyzer.GetAnalyzers(maturities);
    
    foreach (var item in analyzers)
    {
        Console.WriteLine("Min = {0}, \t Max = {1}, \t Current = {2}", item.Min, item.Max, item.Current);
    }
    Console.WriteLine("Press Enter to exit.");
    Console.ReadLine();
    

    Beachten Sie Folgendes:

    • Sie können in C# und F# Verweise zwischen Projekten hinzufügen.

    • In F# definierte Namespaces und Typen können wie andere Typen ebenfalls in C# verarbeitet werden.

    • F#-Dokumentationskommentare sind in C# IntelliSense verfügbar.

    • C# kann auf Tupelrückgabewerte der F#-API zugreifen. Die Tupel sind Tuple-Werte in .NET Framework 4.5.

  4. So debuggen Sie die Anwendung: Drücken Sie F11, um die Anwendung zu erstellen, starten Sie die Anwendung im Debugger, und navigieren Sie zur ersten Zeile des ausgeführten Codes. Drücken Sie so oft F11, bis Sie zum F#-Code im Text des GetAnalyzers-Members gelangen. Beachten Sie Folgendes:

    • Sie können leicht vom F#- zum C#-Code wechseln.

    • Jeder Ausdruck in F# stellt einen Schritt im Debugger dar.

    • Das Lokalfenster zeigt die Werte von maturities an.

    • Drücken Sie wiederholt F11, um durch die Auswertung für den Rest der Anwendung zu springen.

    • Debuggerbefehle, wie Ausführen bis Cursor, Nächste Anweisung festlegen, Haltepunkt einfügen, Überwachung hinzufügen oder Gehe zu Disassembly, funktionieren wie erwartet.

So stellen Sie die Anwendung bereit

  1. Wenn Sie noch debuggen, beenden Sie das Debuggen mit den Tasten UMSCHALT+F5, oder indem Sie das Menü Debuggen öffnen und dann Debuggen beenden wählen.

  2. Öffnen Sie das Kontextmenü für das CSharpDriver-Projekt, und wählen Sie dann Eigenschaften.

  3. Im Projekt-Designer wählen Sie die Registerkarte Veröffentlichen, die Optionen zum Bereitstellen der App enthält.

  4. Wählen Sie die Schaltfläche Webpublishing-Assistent.

    Die Webpublishing-Assistent wird ausgeführt, und auf dem ersten Bildschirm wird gefragt, wo Sie die veröffentlichten Dateien ablegen möchten.

  5. Geben Sie im Textfeld ein, an welchem Speicherort auf dem lokalen Datenträger die Installationsdateien für Ihre App beim Veröffentlichen abgelegt werden sollen, oder wählen Sie die Schaltfläche Durchsuchen, um zu einem Speicherort zu navigieren.

  6. Wählen Sie die Schaltfläche Fertig stellen, um alle Standardwerte für ein Standardsetup zur Verteilung auf Clientcomputer zu übernehmen, oder verwenden Sie die Schaltfläche Weiter, um andere Veröffentlichungsoptionen anzuzeigen.

    Eine ausführbare Setupdatei und unterstützende Dateien werden an dem Speicherort veröffentlicht, den Sie angegeben haben.

Nächste Schritte

Informationen zu den ersten Schritten im F#-Code erhalten Sie unter Exemplarische Vorgehensweise: Ihr erstes F#-Programm, oder lesen Sie Funktionen als erstrangige Werte (F#), um mehr über die Funktionen in F# zu erfahren. Lesen Sie die F#-Sprachreferenz, um ausführliche Informationen über die F#-Programmiersprache zu erhalten.

Siehe auch

Weitere Ressourcen

Beispiele und exemplarische Vorgehensweisen für Visual F#

Beispiele und exemplarische Vorgehensweisen für Visual F#