Sdílet prostřednictvím


Jak: aktualizace modelu UML z podprocesem na pozadí

Někdy může být užitečné, chcete-li změnit model vě vlákně na pozadí.Například pokud načítáte informace z pomalé externích zdrojů, můžete použít podprocesem na pozadí dohlížet aktualizace.To umožňuje uživatelům zobrazit jednotlivé aktualizace ihned poté, co se stane, že.

Musí být však úložiště UML je, že není bezpečné podprocesy.Jsou důležité následující opatření:

  • Každý model nebo diagram aktualizace musí být vyrobeny ve vlákně uživatelského rozhraní (UI).Musíte použít podprocesem na pozadí Invoke nebo Invoke do vlákna uživatelského rozhraní, provést aktualizaci skutečných.

  • Pokud seskupíte sérii změn do jediné transakce, doporučujeme zabránit uživateli v úpravě modelu probíhá transakce.Veškeré úpravy provedené uživatelem v opačném případě se stane součástí stejné transakce.Uživatel může zabránit v provádění změn v zobrazení modálního dialogového okna.Pokud chcete, můžete poskytnout tlačítko Storno v dialogovém okně.Uživatel může zobrazit změny, při jejich provádění.

Příklad

Tento příklad používá podprocesem na pozadí provést několik změn do modelu.Dialogové okno se používá k vyloučení uživatele, je-li spuštěn podproces.V tomto příkladu jednoduchého je k dispozici žádné tlačítko Storno v dialogovém okně.Nicméně by bylo možné snadno přidat funkce.

Chcete-li spustit příklad

  1. Vytvořte obslužnou rutinu příkazu v projektu jazyka C#, jak je popsáno v Postup: definování příkazu nabídky diagramu modelování.

  2. Ujistěte se, zda projekt obsahuje odkazy na tyto sestavení:

    • Microsoft.VisualStudio.ArchitectureTools.Extensibility

    • Microsoft.VisualStudio.Modeling.Sdk.11.0

    • Microsoft.VisualStudio.Modeling.Sdk.Diagrams.11.0

    • Microsoft.VisualStudio.Uml.Interfaces

    • System.ComponentModel.Composition

    • System.Windows.Forms

  3. Do projektu přidáte formulář pro systém Windows s názvem ProgressForm.Zobrazit zpráva oznamující, že aktualizace jsou v průběhu.Nemá žádné ovládací prvky.

  4. Přidejte soubor jazyka C#, který obsahuje kód, který se zobrazí po provedení kroku 7.

  5. Sestavte a spusťte projekt.

    Novou instanci Visual Studio se spustí v režimu experimentální.

  6. Vytvořte nebo otevřete diagram tříd UML v experimentální instanci Visual Studio.

  7. V diagramu UML třídy klepněte pravým tlačítkem myši a potom klepněte na tlačítko Přidat několik tříd UML.

Několik nové třídy se zobrazí pole v diagramu, jeden po druhém v intervalech půl sekundy.

using System;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.Threading;
using System.Windows.Forms;

using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Presentation;
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml;
using Microsoft.VisualStudio.Modeling.ExtensionEnablement;
using Microsoft.VisualStudio.Uml.Classes;

namespace BackgroundThreadProgressUI // CHANGE TO YOUR NAMESPACE
{
  [Export(typeof(ICommandExtension))]
  [ClassDesignerExtension]
  class UmlClassAdderCommand : ICommandExtension
  {

    [Import]
    IDiagramContext context { get; set; }

    [Import]
    ILinkedUndoContext linkedUndoContext { get; set; }

    // Called when the user runs the command.
    public void Execute(IMenuCommand command)
    {
      // The form that will exclude the user.
      ProgressForm form = new ProgressForm();

      // System.ComponentModel.BackgroundWorker is a
      // convenient way to run a background thread.
      BackgroundWorker worker = new BackgroundWorker();
      worker.WorkerSupportsCancellation = true;

      worker.DoWork += delegate(object sender, DoWorkEventArgs args)
      {
        // This block will be executed in a background thread.

        IClassDiagram diagram = context.CurrentDiagram as IClassDiagram;
        IModelStore store = diagram.ModelStore;
        const int CLASSES_TO_CREATE = 15;

        // Group all the changes together.
        using (ILinkedUndoTransaction transaction = linkedUndoContext.BeginTransaction("Background Updates"))
        {
          for (int i = 1; i < CLASSES_TO_CREATE; i++)
          {
            if (worker.CancellationPending) 
               return; // No commit - undo all.

            // Create model elements using the UI thread by using
            // the Invoke method on the progress form. Always 
            // modify the model and diagrams from a UI thread.
            form.Invoke((MethodInvoker)(delegate
            {
              IClass newClass = store.Root.CreateClass();
              newClass.Name = string.Format("NewClass{0}", i);
              diagram.Display(newClass);
            }));
            

            // Sleep briefly so that we can watch the updates.
            Thread.Sleep(500);
          }
          
          // Commit the transaction or it will be rolled back.
          transaction.Commit();
        }
      };

      // Close the form when the thread completes.
      worker.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs args)
      {
        form.Close();
      };

      // Start the thread before showing the modal progress dialog.
      worker.RunWorkerAsync();

      // Show the form modally, parented on VS.       // Prevents the user from making changes while in progress.
      form.ShowDialog();
    }

    public void QueryStatus(IMenuCommand command)
    {
      command.Enabled = command.Visible = true;
    }

    public string Text
    {
      get { return "Add several classes"; }
    }
  }
}

K umožnění uživateli zrušit vlákno v příkladu

  1. Přidáte tlačítko Storno dialogové okno průběhu.

  2. Dialogové okno Průběh přidejte následující kód:

    public event MethodInvoker Cancel;

    private void CancelButton_Click(object sender, EventArgs e)

    {

    Cancel();

    }

  3. V metodě Execute() vložte tento řádek po zhotovení formuláře:

    form.Cancel += delegate() { worker.CancelAsync(); };

Ee941659.collapse_all(cs-cz,VS.110).gifJiné metody přístupu k vlákno uživatelského rozhraní

Pokud nechcete vytvořit dialogové okno, můžete získat přístup k ovládací prvek, který zobrazuje diagramu:

DiagramView uiThreadHolder = context.CurrentDiagram.GetObject<Diagram>().ActiveDiagramView;

Můžete použít uiThreadHolder.Invoke() k provádění operací ve vlákně uživatelského rozhraní.

Viz také

Koncepty

Postup: definování příkazu nabídky diagramu modelování

Postup: definovat speciální tah pro modelování diagramu