2015-05-29 2 views
2

Прежде чем я начну, я хотел бы придумать для любого ... idiocy ..., что я могу показать, когда задаю этот вопрос, я пытаюсь изучить C# после выхода с Java, и просто хотел прыгнуть прямо в него!Консоль «Hangs» при запуске GUI

Я работаю над проектом, который предназначен для выполнения команд через консоль, таких как «play batman начинается», и он начнет играть в фильм «Бэтмен начинается». Он также принимает команды для музыки и т. Д. С этой настройкой моя цель - заставить ее управлять голосом, поэтому я не очень хочу использовать графический интерфейс, а не консоль. Когда у меня есть программа играть в кино, он загружает окно с графическим интерфейсом без рамки, без содержания, и конструктор, который он использует это:

public MainWindow(MediaPlayer player) 
{ 
    InitializeComponent(); 
    VideoDrawing drawing = new VideoDrawing { Rect = new Rect(0, 0, 800, 600), Player = player }; 
    DrawingBrush brush = new DrawingBrush(drawing); 
    Background = brush; 
} 

MediaPlayer управляется от основной функции (на данный момент). Мой код для загрузки видео и запустить это:

MediaPlayer mp = new MediaPlayer(); 
mp.Open(new Uri("C:\\test.mp4", UriKind.RelativeOrAbsolute)); 

VideoDrawing vidDrawing = new VideoDrawing(); 
vidDrawing.Rect = new Rect(0, 0, 100, 100); 
vidDrawing.Player = mp; 

DrawingBrush DBrush = new DrawingBrush(vidDrawing); 
videoPanel = new MainWindow(mp); // GUI panel to play the video on, constructor is listed above 

play(); 
new System.Windows.Application().Run(videoPanel); 

Как я новичок в C# и все, как я получил графический интерфейс для работы с этим, начиная новый проект WPF, создание графического интерфейса пользователя и написав код, а затем скопируйте файлы xaml и cs в мой проект (потому что я ноб, извините). MAYBE это вызывает проблему.

Этот код работает (в основном) в порядке. Когда я запускаю свою программу, она загружает видеофайл, открывает окно и воспроизводит видео на экране во время воспроизведения звука. Однако, когда он запускает видео, GUI «зависает» и не принимает никаких выходных сигналов ИЛИ, но он не заморожен, так как курсор все еще мигает. Я не знаю, почему это так.

Я пробовал нарезать резьбу почти все, о чем я могу думать, но я получаю ошибки с этим. Я попытался локализовать загрузку в окно графического интерфейса пользователя, однако он все еще висит на консоли. В течение последних нескольких дней я искал в Интернете всевозможные вещи и не мог найти решение, поэтому я перевернулся!

В моей программе гораздо больше занятий и вещей, поэтому мне пришлось сбрасывать все это вместе и проверять дважды, поэтому, если мне что-то не хватает или глупо, сообщите мне, и я могу это исправить , Поскольку я все еще новичок в C# (но не новичок в программировании), я, возможно, тоже что-то пропустил в своих подробностях.

Мне интересно, будет ли решение сделать это на всех графических интерфейсах, а не на гибридной консоли и графическом интерфейсе? Из-за информации, которую я нашел в Интернете, похоже, могут быть некоторые раздражающие ... несоответствия ... между двумя типами потоков?

В любом случае, любая помощь будет замечательной, я потратил последние 3 дня, пытаясь отладить это и не добился какого-либо прогресса. Если это помогает, есть ссылка на репо here! Спасибо :)

EDIT: Я сделал некоторые изменения, ожидая ответа, прежде всего изменив способ его рисования в графическом интерфейсе. Первоначально я рисовал его на заднем плане, но теперь обработал его через MediaElement. Это целый класс для моего окна в настоящее время:

public partial class MainWindow : Window 
    { 

     public MainWindow(string dir) 
     { 
      InitializeComponent(); 

      video.Source = new Uri(dir); //video is the name of my MediaElement 
     } 

     public void pause(){ 
      video.Pause(); 
     } 

     public void resume() 
     { 
      video.Play(); 
     } 

     public void stop() 
     { 
      video.Stop(); 
      this.Close(); 
     } 

     public void volume(int i) 
     { 
      video.Volume = i; 
     } 
    } 

Это не исправить консоль Ханг, однако это сделало все гораздо более централизованной, с тем, чтобы сделать отладку легче. Надеюсь, это поможет!

ответ

1

Рассмотрите возможность преобразования этого в WPF-приложение, это упростит ситуацию.

В любом случае, вы все равно можете работать с графическим интерфейсом без блокировки консоли, но вы должны выполнять связанные с GUI материалы в отдельном выделенном потоке STA.Так как вы используете WPF, этот помощник должен быть полезным (этот код не является производство качественной, но работает):

static class UIThread 
{ 
    private static Dispatcher _dispatcher; 

    public static void Start() 
    { 
     using(var wh = new ManualResetEvent(false)) 
     { 
      var thread = new Thread(ThreadProc) 
      { 
       IsBackground = true, 
      }; 
      thread.SetApartmentState(ApartmentState.STA); 
      thread.Start(wh); 
      wh.WaitOne(); 
     } 
    } 

    private static void ThreadProc(object arg) 
    { 
     var wh = (EventWaitHandle)arg; 
     _dispatcher = Dispatcher.CurrentDispatcher; 
     wh.Set(); 
     Dispatcher.Run(); 
    } 

    public static Dispatcher Dispatcher 
    { 
     get { return _dispatcher; } 
    } 
} 

Этот помощник предоставляет ссылки на Dispatcher объект, который используется для выполнения методов на Пользовательский интерфейс.

Все коммуникации с потоком пользовательского интерфейса должны быть выполнены с помощью методов Dispatcher.Invoke() или Dispatcher.BeginInvoke(). Обратите внимание, что поскольку теперь у нас есть несколько потоков, в потоке пользовательского интерфейса должны быть созданы объекты MediaPlayer. Вы можете по-прежнему удерживать ссылку на любом потоке, который хотите, но любой вызов метода для объекта MediaPlayer должен пройти через Dispatcher.

Вещи изменения:

  • добавить UIThread.Start(); вызов до попытки использовать Dispatcher. Начало метода Main() - хорошее место для этого.
  • MediaPlayer объекты должны быть созданы таким образом: mediaPlayer = UIThread.Dispatcher.Invoke(() => new Media());
  • любой UI-код, связанный должен перейти к Dispatcher.Invoke() или Dispatcher.BeginInvoke(): UIThread.Dispatcher.BeginInvoke(() => playVideo(@"C:\video.avi"));

Update

Также изменить new System.Windows.Application().Run(videoPanel); к простому videoPanel.Show(). Application.Run() блокируется до закрытия окна.

+0

Так что, чтобы быть понятным, это, вероятно, устранит проблему, однако проще всего преобразовать все в приложение WPF? – PulsePanda

+0

Хорошо, вот что у меня получилось: UIThread.Start(); mediaPlayer = UIThread.Dispatcher.Invoke (() => new Media()); UIThread.Dispatcher.Invoke (() => mediaPlayer.playVideo ("C: \\ test.mp4")); это все еще приводит к «зависанию». Есть предположения? – PulsePanda

+0

Измените второй вызов на использование 'BeginInvoke()': 'UIThread.Dispatcher.BeginInvoke (() => mediaPlayer.playVideo (" C: \\ test.mp4 "));' – max

Смежные вопросы