@markula

Почему виснет приложение и почему не работает сериализация?

Пишу курсач на WPF. Приложение с прыгающим текстом. При нажатии на форму текст должен переставать/начинать прыгать. Также нужно реализовать сериализацию.
Возникло 2 проблемы:
1. При нажатии на форм(для приостановки/возобновления потока в которой прыгает текст) приложение может зависнуть(иногда виснет, иногда нет).
2. При попытке сериализовать приложение нажатием на кнопку вылетает исключение:
Необработанное исключение типа "System.InvalidOperationException" в System.Xml.dll Дополнительные сведения: Возникла ошибка при отражении типа "MyNervousText.MainWindow".

Исходник:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Threading;
using System.Xml.Serialization;
using System.IO;
namespace MyNervousText
{
    /// <summary>
    /// Логика взаимодействия для MainWindow.xaml
    /// </summary>
    [Serializable]
    public partial class MainWindow : Window
    {
        public static Label lbl1 = new Label();
        public static Label timer = new Label();
        public static Thread killme = null;
        public static Thread timerenew;
        public static string s;
        public static ImageBrush ib = new ImageBrush();
        public static BitmapImage bi = new BitmapImage();
        public static Boolean threadSuspended = false;
        public static Button serialize = new Button();
        public string data;
        //метод вызывающий главное окно
        public MainWindow()
        {
            InitializeComponent();
            bi.BeginInit();
            bi.UriSource = new Uri("c:/users/markula/documents/visual studio 2013/Projects/MyNervousText/MyNervousText/Resources/Синий экран.png");
            bi.EndInit();
            this.Content = appLogic.grd;
            appLogic.setGrid();
            this.Width = 1000;
            this.Height = 1000;
            this.Background = ib;
            ib.ImageSource = bi;
            this.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen;


            serialize.Height = 50;
            serialize.Width = 100;
            serialize.Content = "сохранить";
            serialize.Click += serialize_Click;

            //Поток часов
            timerenew = new Thread(Runt);
            timerenew.Start();
            //Поток текста
            killme = new Thread(Run);
            killme.Start();
            //События
            this.Closing += MainWindow_Closing; // Подписываемся на событие "закрытие окна"
            this.MouseDown += MainWindow_MouseDown; // Подписываемся на событие "нажатие мыши"
        }
        //метод запусающий поток Runt
        public void Runt()
        {
            this.Dispatcher.BeginInvoke((ThreadStart)delegate()
            {                
                appLogic.setTime();
            });
        }
        //метод запусающий поток Killme
        public void Run()
        {
            while (killme != null)
            {
                Thread.Sleep(TimeSpan.FromMilliseconds(50));//задержка 50мс
                paint();
            }
        }
        //Метод отрисовки текста
        public void paint()
        {
            this.Dispatcher.BeginInvoke((ThreadStart)delegate()
            {
                appLogic.paint();

            });
        }

        //нажатие кнопки serialize
        public void serialize_Click(object sender, RoutedEventArgs e)
        {
            SaveAsXmlFormat(this, @"MnWndSave");
        }
        //метод сериализирующий приложение
        public static void SaveAsXmlFormat(object objGraph, string fileName)
        {
            XmlSerializer xmlFormat = new XmlSerializer(typeof(MainWindow));
            using (Stream fStream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                xmlFormat.Serialize(fStream, objGraph);
            }
        }

        //метод закрытия окна
        private void MainWindow_Closing(object sender,System.ComponentModel.CancelEventArgs e)
        {
            appLogic.close();
        }

        //метод нажатия кнопки мыши, который должен приостанавливать/возобновлять поток
        private void MainWindow_MouseDown(object sender, MouseEventArgs e)
        {
            appLogic.ssprsm();
        }
   }
    public class appLogic
    {
        public static Grid grd = new Grid();
        public static void setGrid()
        {
            //сетка:создание столбцов и строк
            ColumnDefinition colDef1 = new ColumnDefinition();
            ColumnDefinition colDef2 = new ColumnDefinition();
            ColumnDefinition colDef3 = new ColumnDefinition();
            grd.ColumnDefinitions.Add(colDef1);
            grd.ColumnDefinitions.Add(colDef2);
            grd.ColumnDefinitions.Add(colDef3);
            RowDefinition rowDef1 = new RowDefinition();
            RowDefinition rowDef2 = new RowDefinition();
            RowDefinition rowDef3 = new RowDefinition();
            grd.RowDefinitions.Add(rowDef1);
            grd.RowDefinitions.Add(rowDef2);
            grd.RowDefinitions.Add(rowDef3);
            //сетка:добавление метки lbl1
            Grid.SetRow(MainWindow.lbl1, 0);
            Grid.SetColumn(MainWindow.lbl1, 0);
            grd.Children.Add(MainWindow.lbl1);
            //сетка:добавление метки timer
            Grid.SetRow(MainWindow.timer, 0);
            Grid.SetColumn(MainWindow.timer, 2);
            grd.Children.Add(MainWindow.timer);
            //сетка:добавление кнопки serialize
            Grid.SetRow(MainWindow.serialize, 3);
            Grid.SetRow(MainWindow.serialize, 3);
            grd.Children.Add(MainWindow.serialize);
        }
        public static void setTime()
        {
                MainWindow.timer.Content = DateTime.Now;
                MainWindow.timer.Foreground = Brushes.Blue;
                MainWindow.timer.FontSize = 40;
                MainWindow.timer.HorizontalAlignment = HorizontalAlignment.Right;
        }
        public static void paint()
        {
            MainWindow.lbl1.Foreground = Brushes.White;
            MainWindow.lbl1.Content = "Прыгающий Текст";
            MainWindow.lbl1.FontSize = 30;
            MainWindow.s = MainWindow.lbl1.Content.ToString();
            for (int i = 0; i < MainWindow.s.Length; i++)
            {
                Random rnd = new Random();
                double rand = rnd.NextDouble();
                MainWindow.lbl1.Margin = new Thickness(rand * 1 + 1 * i, rand * 5 + 13, 0, 0);
            }
        }
        public static void close()
        {
            if (MainWindow.threadSuspended)
            {
                MainWindow.killme.Resume();
            }
            MainWindow.killme.Abort();
            MainWindow.timerenew.Abort();
        }
        public static void ssprsm()
        {
            if (MainWindow.threadSuspended)
            {
                MainWindow.killme.Resume();
            }
            else
            {
                MainWindow.killme.Suspend();
            }
            MainWindow.threadSuspended = !MainWindow.threadSuspended;
        }
    }
}
  • Вопрос задан
  • 3010 просмотров
Пригласить эксперта
Ответы на вопрос 1
sintez
@sintez
1. Зачем в данной задаче использовать потоки, тем более целых два? Посмотрите в сторону DispatcherTimer, и всю логику по отрисовке часов перенесите в обработчик события Tick. Прыгающий текст правильнее было бы реализовать средствами для анимации, которые предоставляет WPF. Почитайте про Storyboard.
2. Не понимаю, зачем сериализовывать саму форму. Этого действительно требует задание? Возможно, вам требовалось сериализовать состояние приложения, а не саму форму?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы