gpt4 book ai didi

c# - GUI 启动时的控制台 "Hangs"

转载 作者:太空宇宙 更新时间:2023-11-03 13:06:48 25 4
gpt4 key购买 nike

在我开始之前,我想为任何...白痴...道歉,我在问这个问题时可能会表现出来,我在从 Java 转过来后正在尝试学习 C#,只是想直接进入它!

我正在开发一个旨在通过控制台接受命令的项目,例如“播放 bat 侠开始”,它将开始播放电影《 bat 侠开始》。它还接受音乐等命令。通过此设置,我的目标是让它语音控制,所以我并不真正关心使用 GUI 而不是控制台。当我让程序播放电影时,它会加载一个没有边框、没有内容的 GUI 窗口,它使用的构造函数是:

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# 的新手,我使用 GUI 的方法是启动一个新的 WPF 项目,创建 GUI 并编写代码,然后将 xaml 和 cs 文件复制粘贴到我的项目中(因为我是菜鸟,对不起)。可能这是导致问题的原因。

此代码(大部分)工作正常。当我运行我的程序时,它加载视频文件,打开窗口,并在播放声音的同时在屏幕上播放视频。但是,当它开始播放视频时,GUI“挂起”并且不接受任何输入或输出,但它并没有卡住,因为光标仍在闪烁。我不确定这是为什么。

我已经尝试过对几乎所有我能想到的线程进行线程处理,但我遇到了错误。我已经尝试将加载本地化到 GUI 窗口本身,但它仍然挂起控制台。这几天在网上找了各种东西都找不到解决办法,所以才转过来!

我的程序有更多的类和东西在进行,所以我不得不把所有这些东西放在一起,并仔细检查,所以如果我遗漏了什么或犯了一个愚蠢的错误,请告诉我,我可以修复它。由于我对 C# 还是有点陌生​​(但对编程并不陌生),我可能也遗漏了问题详细信息中的一些内容。

我想知道解决方案是否是全部基于 GUI,而不是混合控制台和 GUI?根据我在网上找到的信息,两种类型的线程之间似乎存在一些烦人的...差异...?

无论如何,任何帮助都会很棒,过去 3 天我一直在尝试调试它,但没有取得任何进展。如果有帮助,这里有一个指向 repo here 的链接!谢谢:)

编辑:我在等待响应时做了一些更改,主要是更改了它绘制到 GUI 的方式。最初我让它在背景上绘画,但现在让它通过 MediaElement 进行处理。这是我窗口的整个类(class):

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;
}
}

这并没有解决控制台挂起的问题,但是这使一切都更加集中,从而使调试更加容易。希望这可能有所帮助!

最佳答案

考虑将其转换为 WPF 应用程序,这会使事情变得更容易。

无论如何,您仍然可以在不锁定控制台的情况下使用 GUI,但是您必须在单独的专用 STA 线程上执行与 GUI 相关的内容。由于您使用的是 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 对象的引用,该对象用于在 UI 线程上执行方法。

与 UI 线程的所有通信都应通过 Dispatcher.Invoke()Dispatcher.BeginInvoke() 方法完成。请注意,由于我们现在有多个线程,因此必须在 UI 线程上创建 MediaPlayer 对象。您仍然可以在任何线程上保留它的引用,但是对 MediaPlayer 对象的任何方法调用都必须通过 Dispatcher

要改变的事情:

  • 在尝试使用 Dispatcher 之前添加一个 UIThread.Start(); 调用。 Main() 方法的开头是执行此操作的好地方。
  • MediaPlayer 对象应该像这样创建:mediaPlayer = UIThread.Dispatcher.Invoke(() => new Media());
  • 任何与 UI 相关的代码都应该转到 Dispatcher.Invoke()Dispatcher.BeginInvoke():UIThread.Dispatcher.BeginInvoke(() => playVideo(@"C:\video.avi"));

更新

同时将 new System.Windows.Application().Run(videoPanel); 更改为简单的 videoPanel.Show()Application.Run() 阻塞,直到窗口关闭。

关于c# - GUI 启动时的控制台 "Hangs",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30540018/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com