多个GUI线程和多个错误

时间:2015-03-04 14:48:28

标签: c# wpf multithreading xaml

首先是对我的应用的简短解释。我必须在每台PC上以8到16个屏幕呈现我的应用程序。在每个屏幕上是应用程序的另一部分。有些人正在无休止地重复播放视频,有些正在展示无休止的重复幻灯片,有些则具有更多功能。有些屏幕甚至是触摸屏,因此它也必须是交互式的。但是当我在一个线程上调用16个窗口时,你可以想象会发生什么...... 所以我使用以下选项: 在App.xaml.cs中,我使用foreach并浏览所有屏幕。每个屏幕都有一个xml文件中的配置,并使用screennumber和它应显示的内容进行调用。

但几乎在任何一开始它都会因为另一个错误消息而崩溃。我只能想到使用这种多GUI线程的内存错误。有时候我会得到未知的错误,有时候XML-Query会崩溃,有时它会成为IOStream,等等......

有人知道我能做得更好吗?我在哪里可以优化设置?或者我怎样才能显示多个带视频的窗口等等而不会相互冻结?

为了更好地理解我在做什么,我将代码粘贴到此处。

这是XAML:

<Window x:Class="ASA_Videowand.WheelOfFortune"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="WheelOfFortune" 
    Name="WheelWindow"
    WindowStyle="None"
    Height="1080" 
    Width="1920"
    Loaded="WheelOfFortune_OnLoaded">
<Window.Resources>
    <Style x:Key="ImgZIndexStyle" TargetType="{x:Type Image}">
        <Setter Property="Panel.ZIndex" Value="2"/>
        <Style.Triggers>
            <Trigger Property="Image.Opacity" Value="1">
                <Setter Property="Panel.ZIndex" Value="3"/>
            </Trigger>
        </Style.Triggers>
    </Style>
    <Storyboard x:Key="FaderStoryboardHide1Show2">
        <DoubleAnimation Storyboard.TargetName="FirstImage" 
         Storyboard.TargetProperty="Opacity"
         To="0" Duration="0:00:01" />
        <DoubleAnimation Storyboard.TargetName="SecondImage" 
         Storyboard.TargetProperty="Opacity"
         To="1" Duration="0:00:01" />
    </Storyboard>
    <Storyboard x:Key="FaderStoryboardHide2Show1">
        <DoubleAnimation Storyboard.TargetName="SecondImage" 
         Storyboard.TargetProperty="Opacity"
         To="0" Duration="0:00:01" />
        <DoubleAnimation Storyboard.TargetName="FirstImage" 
         Storyboard.TargetProperty="Opacity"
         To="1" Duration="0:00:01" />
    </Storyboard>
</Window.Resources>
<Grid>
    <Grid Name="SlideShowGrid" ZIndex="0">
        <Image x:Name="FirstImage" Stretch="UniformToFill" Style="{StaticResource ImgZIndexStyle}" Opacity="1" />
        <Image x:Name="SecondImage" Stretch="UniformToFill" Style="{StaticResource ImgZIndexStyle}" Opacity="0"/>
    </Grid>
    <Canvas Name="VideoCanvas" ZIndex="0">
        <Button Name="VideoButton" Click="VideoButton_OnClick">
            <MediaElement Height="{Binding ElementName=WheelWindow, Path=Height}" 
                          Width="{Binding ElementName=WheelWindow, Path=Width}"
                          UnloadedBehavior="Manual"
                          MediaEnded="MarketingVideoMediaElement_OnMediaEnded"
                          Name="MarketingVideoMediaElement" />
        </Button>
    </Canvas>
    <Grid Name="WheelGrid" ZIndex="1">
        <Button Name="SpinWheelButton" Click="SpinWheelButton_OnClick">
            <Grid>
                <Image Source="pics/gluecksrad_background.jpg" Stretch="UniformToFill" />
                <Border>
                    <Border.Effect>
                        <DropShadowEffect Direction="330" Opacity="0.7" ShadowDepth="5" Color="Black" BlurRadius="3" RenderingBias="Performance" />
                    </Border.Effect>
                    <Image Name="ArrowImage" Source="pics/pfeil.png" Height="300" RenderTransformOrigin="0.5,0.5" Margin="414,330,1390,420">
                        <Image.RenderTransform>
                            <RotateTransform />
                        </Image.RenderTransform>
                    </Image>
                </Border>
            </Grid>
        </Button>
    </Grid>
</Grid>

WheelOfFortune.xaml.cs:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
using Microsoft.Win32;
using Panel = System.Windows.Controls.Panel;

namespace ASA_Videowand
{
    public partial class WheelOfFortune
    {
        private int _listCounter;
        private int _imageCounter;
        private int _countTimer;
        private int _screenNumber;
        private List<string> _fileList;
        private DoubleAnimation _rotateAnimation;
        private readonly int _imageChangeTime;
        private readonly string _myPath;
        private readonly List<int> _targetAngelList = new List<int>();
        private readonly DispatcherTimer _videoTimer = new DispatcherTimer();
        private readonly DispatcherTimer _slideShowTimer = new DispatcherTimer();
        private static readonly object MyLock = new object();

        public WheelOfFortune(int screenNumber, string configName)
        {
            lock (MyLock)
            {
                InitializeComponent();
            }
            BuildList();
            CreateVideoTimer();
            _screenNumber = screenNumber;
            var regKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32);
            var openSubKey = regKey.OpenSubKey(@"SOFTWARE\ASA\Videowand", false);
            if (openSubKey != null)
            {
                _myPath = openSubKey.GetValue("ProgramPath").ToString();
                _imageChangeTime = Convert.ToInt32(openSubKey.GetValue("SlideShowTimer"));
            }
            GetDataFromHdd(configName);
        }

        private void GetDataFromHdd(string configName)
        {
            foreach (var fileList in from subDirectory in Directory.GetDirectories(_myPath, "*", SearchOption.AllDirectories) 
                                 where subDirectory.Contains(configName) 
                                 select Directory.GetFiles(subDirectory, "*", SearchOption.TopDirectoryOnly).ToList())
            {
                if (fileList[0].ToUpper().Contains(".JPG") || fileList[0].ToUpper().Contains(".GIF") ||
                fileList[0].ToUpper().Contains(".JPEG") || fileList[0].ToUpper().Contains(".PNG") ||
                fileList[0].ToUpper().Contains(".TIFF") || fileList[0].ToUpper().Contains(".BMP"))
                {
                    _fileList = fileList;
                    BuildSlideShow();
                }
                else
                    ShowMovie(fileList[0]);
            }
        }

        private void ShowMovie(string fileName)
        {
            CreateVideoStoryboard();
            Panel.SetZIndex(VideoCanvas, 2);
            MarketingVideoMediaElement.Source = new Uri(fileName);
        }

        private void BuildSlideShow()
        {
            Panel.SetZIndex(SlideShowGrid, 2);
            WheelGrid.Opacity = 0;
            FirstImage.Source = new BitmapImage(new Uri(_fileList[0]));
            _slideShowTimer.Interval = new TimeSpan(0, 0, _imageChangeTime);
            _slideShowTimer.Tick += Timer_Tick;
            _slideShowTimer.Start();
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            System.Windows.Controls.Image newImage;
            Storyboard tempStoryboard;
            if (FirstImage.Opacity == 1)
            {
                tempStoryboard = (Storyboard) FindResource("FaderStoryboardHide1Show2");
                newImage = SecondImage;
            }
            else
            {
                tempStoryboard = (Storyboard)FindResource("FaderStoryboardHide2Show1");
                newImage = FirstImage;
            }
            if (_imageCounter >= _fileList.Count - 1)
                _imageCounter = 0;
            else
                _imageCounter++;
            newImage.Source = new BitmapImage(new Uri(_fileList[_imageCounter]));
            tempStoryboard.Begin();
        }

        private void CreateVideoTimer()
        {
            _videoTimer.Interval = TimeSpan.FromSeconds(1);
            _videoTimer.Tick += VideoTimerOnTick;
        }

        private void VideoTimerOnTick(object sender, EventArgs eventArgs)
        {
            _countTimer++;
            if (_countTimer <= 8) return;
            Panel.SetZIndex(VideoCanvas, 2);
            _videoTimer.Stop();
            _countTimer = 0;
        }

        private void BuildList()
        {
            _targetAngelList.Add(11); // 1 Chip
            _targetAngelList.Add(33); // 1 Chip
            _targetAngelList.Add(56); // 1 Chip
            _targetAngelList.Add(78); // 0 Chips
            _targetAngelList.Add(101); // 2 Chips
            _targetAngelList.Add(123); // 0 Chips
            _targetAngelList.Add(146); // 1 Chip
            _targetAngelList.Add(168); // 1 Chip
            _targetAngelList.Add(191); // 1 Chip
            _targetAngelList.Add(214); // 1 Chip
            _targetAngelList.Add(237); // 1 Chip
            _targetAngelList.Add(259); // 1 Chip
            _targetAngelList.Add(281); // 0 Chips
            _targetAngelList.Add(304); // 2 Chips
            _targetAngelList.Add(327); // 0 Chips
            _targetAngelList.Add(349); // 1 Chip
        }

        private void SpinWheelButton_OnClick(object sender, RoutedEventArgs e)
        {
            _countTimer = 0;
            var targetAngel = new Random();
            _listCounter = targetAngel.Next(0, _targetAngelList.Count - 1);
            _rotateAnimation.To = 1800 + _targetAngelList[_listCounter];
            ((Storyboard)Resources["Storyboard"]).Begin();
        }

        private void CreateVideoStoryboard()
        {
            var spinningStoryboard = new Storyboard
            {
                Duration = new Duration(TimeSpan.FromMilliseconds(2500)),
            };
            _rotateAnimation = new DoubleAnimation
            {
                From = 0,
                To = 1800 + _targetAngelList[_listCounter],
                Duration = spinningStoryboard.Duration,
                DecelerationRatio = 0.9
            };
            Storyboard.SetTarget(_rotateAnimation, ArrowImage);
            Storyboard.SetTargetProperty(_rotateAnimation, new PropertyPath("(UIElement.RenderTransform).(RotateTransform.Angle)"));
            spinningStoryboard.Children.Add(_rotateAnimation);
            Resources.Add("Storyboard", spinningStoryboard);
        }

        private void VideoButton_OnClick(object sender, RoutedEventArgs e)
        {
            Panel.SetZIndex(VideoCanvas, 0);
            _videoTimer.Start();
        }

        private void MarketingVideoMediaElement_OnMediaEnded(object sender, RoutedEventArgs e)
        {
            MarketingVideoMediaElement.Position = new TimeSpan(0, 0, 0, 0, 1);
            MarketingVideoMediaElement.Play();
        }

        private void WheelOfFortune_OnLoaded(object sender, RoutedEventArgs e)
        {
            ShowOnMonitor();
        }

        private void ShowOnMonitor()
        {
            Screen[] screenArray = Screen.AllScreens;
            if (_screenNumber >= screenArray.Length)
            {
                _screenNumber = 0;
            }
            Left = Convert.ToInt32(screenArray[_screenNumber].Bounds.Left);
            Top = Convert.ToInt32(screenArray[_screenNumber].Bounds.Top);
            WindowState = WindowState.Maximized;
        }
    }
}

0 个答案:

没有答案
相关问题