2017-07-19 2 views
0

J'utilise un contrôle utilisateur que j'ai trouvé en ligne pour exprimer le traitement.Une fenêtre enfant bloque le thread principal

Ce que j'essaye de faire montre une fenêtre contenant ce contrôle d'utilisateur jusqu'à ce que le fil principal finisse le traitement.

C'est le code de contrôle de l'utilisateur:

public partial class CircularProgressBar 
{ 
    #region Data 

    private readonly DispatcherTimer animationTimer; 

    #endregion 

    #region Constructor 

    public CircularProgressBar() 
    { 
     InitializeComponent(); 

     animationTimer = new DispatcherTimer(DispatcherPriority.ContextIdle, Dispatcher); 
     animationTimer.Interval = new TimeSpan(0, 0, 0, 0, 75); 
    } 

    #endregion 

    #region Private Methods 

    private void Start() 
    { 
     Mouse.OverrideCursor = Cursors.Wait; 
     animationTimer.Tick += HandleAnimationTick; 
     animationTimer.Start(); 
    } 

    private void Stop() 
    { 
     animationTimer.Stop(); 
     Mouse.OverrideCursor = Cursors.Arrow; 
     animationTimer.Tick -= HandleAnimationTick; 
    } 

    private void HandleAnimationTick(object sender, EventArgs e) 
    { 
     SpinnerRotate.Angle = (SpinnerRotate.Angle + 36) % 360; 
    } 

    private void HandleLoaded(object sender, RoutedEventArgs e) 
    { 
     const double offset = Math.PI; 
     const double step = Math.PI * 2/10.0; 

     SetPosition(C0, offset, 0.0, step); 
     SetPosition(C1, offset, 1.0, step); 
     SetPosition(C2, offset, 2.0, step); 
     SetPosition(C3, offset, 3.0, step); 
     SetPosition(C4, offset, 4.0, step); 
     SetPosition(C5, offset, 5.0, step); 
     SetPosition(C6, offset, 6.0, step); 
     SetPosition(C7, offset, 7.0, step); 
     SetPosition(C8, offset, 8.0, step); 
    } 

    private void SetPosition(Ellipse ellipse, double offset, double posOffSet, double step) 
    { 
     ellipse.SetValue(Canvas.LeftProperty, 50.0 + Math.Sin(offset + posOffSet * step) * 50.0); 
     ellipse.SetValue(Canvas.TopProperty, 50 + Math.Cos(offset + posOffSet * step) * 50.0); 
    } 

    private void HandleUnloaded(object sender, RoutedEventArgs e) 
    { 
     Stop(); 
    } 

    private void HandleVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) 
    { 
     bool isVisible = (bool)e.NewValue; 

     if (isVisible) 
      Start(); 
     else 
      Stop(); 
    } 

    #endregion 
} 

XAML:

<UserControl Height="Auto" Width="Auto" Background="Transparent" IsVisibleChanged="HandleVisibleChanged"> 
    <Grid x:Name="LayoutRoot" Background="Transparent" ToolTip="Searching...." HorizontalAlignment="Center" VerticalAlignment="Center"> 
     <Canvas RenderTransformOrigin="0.5,0.5" 
       HorizontalAlignment="Center" 
      VerticalAlignment="Center" Width="120" 
      Height="120" Loaded="HandleLoaded" 
       Unloaded="HandleUnloaded" > 
      <Ellipse x:Name="C0" Width="20" Height="20" Canvas.Left="0" Canvas.Top="0" Stretch="Fill" Fill="Black" Opacity="1.0"/> 
      <Ellipse x:Name="C1" Width="20" Height="20" 
        Canvas.Left="0" 
        Canvas.Top="0" Stretch="Fill" 
        Fill="Black" Opacity="0.9"/> 
      <Ellipse x:Name="C2" Width="20" Height="20" 
        Canvas.Left="0" 
        Canvas.Top="0" Stretch="Fill" 
        Fill="Black" Opacity="0.8"/> 
      <Ellipse x:Name="C3" Width="20" Height="20" 
        Canvas.Left="0" 
        Canvas.Top="0" Stretch="Fill" 
        Fill="Black" Opacity="0.7"/> 
      <Ellipse x:Name="C4" Width="20" Height="20" 
        Canvas.Left="0" 
        Canvas.Top="0" Stretch="Fill" 
        Fill="Black" Opacity="0.6"/> 
      <Ellipse x:Name="C5" Width="20" Height="20" 
        Canvas.Left="0" 
        Canvas.Top="0" Stretch="Fill" 
        Fill="Black" Opacity="0.5"/> 
      <Ellipse x:Name="C6" Width="20" Height="20" 
        Canvas.Left="0" 
        Canvas.Top="0" Stretch="Fill" 
        Fill="Black" Opacity="0.4"/> 
      <Ellipse x:Name="C7" Width="20" Height="20" 
        Canvas.Left="0" 
        Canvas.Top="0" Stretch="Fill" 
        Fill="Black" Opacity="0.3"/> 
      <Ellipse x:Name="C8" Width="20" Height="20" 
        Canvas.Left="0" 
        Canvas.Top="0" Stretch="Fill" 
        Fill="Black" Opacity="0.2"/> 
      <Canvas.RenderTransform> 
       <RotateTransform x:Name="SpinnerRotate" 
        Angle="0" /> 
      </Canvas.RenderTransform> 
     </Canvas> 
    </Grid> 
</UserControl> 

J'utilise ce contrôle utilisateur dans une fenêtre et appeler cette fenêtre quand je commence le traitement à l'aide:

private void ThreadStartingPoint() 
{ 
    Window.Show(); 
    Window.Focus(); 
    System.Windows.Threading.Dispatcher.Run(); 
} 

Ceci bloque l'exécution du thread principal, je ne sais pas ce que j'ai fait de mal car je suis nouveau à cette .

Répondre

1

Dispatcher.Run est certainement bloquant. Vous ne pouvez pas appeler cette méthode sur le thread principal sans bloquer.

Si vous voulez créer une nouvelle fenêtre sur un fil dédié pour une raison quelconque, vous pouvez consulter le blog de @Reed Copsey:

Lancement d'une fenêtre WPF dans un thread séparé, Partie 1:http://reedcopsey.com/2011/11/28/launching-a-wpf-window-in-a-separate-thread-part-1/

il explique comment faire correctement:

// Create a thread 
Thread newWindowThread = new Thread(new ThreadStart(() => 
{ 
    // Create our context, and install it: 
    SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext(Dispatcher.CurrentDispatcher)); 

    Window1 tempWindow = new Window1(); 
    tempWindow.Content = new CircularProgressBar(); 
    // When the window closes, shut down the dispatcher 
    tempWindow.Closed += (s, e) => 
    Dispatcher.CurrentDispatcher.BeginInvokeShutdown(DispatcherPriority.Background); 

    tempWindow.Show(); 
    // Start the Dispatcher Processing 
    System.Windows.Threading.Dispatcher.Run(); 
})); 
// Set the apartment state 
newWindowThread.SetApartmentState(ApartmentState.STA); 
// Make the thread a background thread 
newWindowThread.IsBackground = true; 
// Start the thread 
newWindowThread.Start(); 
+0

grâce, dans ce cas, comment pourrais-je pouvoir le fermer du fil conducteur? –

+0

Utilisation du répartiteur de la fenêtre. Mais s'il vous plaît poser une nouvelle question si vous avez un autre problème. – mm8