我正在寻找我遇到的以下问题的帮助。
我花了两天时间通过这个网站搜索并通过谷歌 - 尝试了许多不同的事情来解决我的问题,到目前为止我没有运气。我知道我还没有对多线程做足够的阅读,这将是我学习之旅中的下一个待办事项。我是C#的新手,所以请保持温和。
我的主要WPF应用程序有一个按钮,我将其标记为“INFO”。在“INFO”按钮的CLICK事件中,我需要启动一个单独的WPF,它只包含WEBBROWSER对象。我在webbrowser对象中显示我们的Intranet站点。
我需要能够完成以下任务:
我正在寻找最简单的解决方案。
我所拥有的示例代码
//这是在公共MainWindow()上面声明的 线程newWindowThread;
private async void btn_LaunchWPFBrowser_Click(object sender, RoutedEventArgs e)
{
try
{
if (newWindowThread == null)
{
newWindowThread = new Thread(() =>
{
var wpfwindow = new WPF_Windows.wpf_Browser();
wpfwindow.Show();
wpfwindow.Closed += (sender2, e2) => wpfwindow.Dispatcher.InvokeShutdown();
// Start the Dispatcher Processing
System.Windows.Threading.Dispatcher.Run();
});
// Set the apartment state
newWindowThread.SetApartmentState(ApartmentState.STA); //setting new thread’s apartment state to STA, this is a WPF requirement
newWindowThread.Start();
}
else if (newWindowThread.ThreadState == ThreadState.Running)
{
//wpfwindow.Activate();
}
}
catch (Exception ex)
{
string additionalMessage = "In method '" + TraceCallerClass.TraceCaller() + "' ";
MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
答案 0 :(得分:0)
你走了:
private object syncGate = new object();
private Thread browserWindowThread;
private Window browserWindow;
private void btn_LaunchWPFBrowser_Click(object sender, RoutedEventArgs e)
{
try
{
lock (syncGate)
{
if (browserWindowThread == null)
{
browserWindowThread = new Thread(() =>
{
var wpfwindow = new WPF_Windows.wpf_Browser();
wpfwindow.Show();
wpfwindow.Closed += (sender2, e2) => wpfwindow.Dispatcher.InvokeShutdown();
lock (syncGate)
browserWindow = wpfwindow;
// Start the Dispatcher Processing
System.Windows.Threading.Dispatcher.Run();
lock (syncGate)
{
browserWindow = null;
browserWindowThread = null;
}
});
browserWindowThread.IsBackground = true;
// Set the apartment state
browserWindowThread.SetApartmentState(ApartmentState.STA); //setting new thread’s apartment state to STA, this is a WPF requirement
browserWindowThread.Start();
}
else if (browserWindow != null)
{
browserWindow.Dispatcher.BeginInvoke(new Func<bool>(browserWindow.Activate));
}
}
}
catch (Exception ex)
{
string additionalMessage = "In method '" + TraceCallerClass.TraceCaller() + "' ";
MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
lock (syncGate)
{
if (browserWindow != null)
browserWindow.Dispatcher.BeginInvoke(new Action(browserWindow.Close));
}
}
答案 1 :(得分:0)
使用Task而不是Thread来轻松关闭进程。 我的提议使用这种方式...
public interface IWinOwnerCollection
{
List<Window> WinOwnerCollection { get; }
}
class MainWindow : Window, IWinOwnerCollection
{
public List<Window> WinOwnerCollection { get; private set; }
Task newWindowTask;
public MainWindow()
{
InitializeComponent();
WinOwnerCollection = new List<Window>();
this.Closed += (sender, args) =>
{
newWindowTask = null;
};
}
private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
try
{
if (newWindowTask == null)
{
newWindowTask = new Task(() =>
{
Dispatcher.Invoke(() =>
{
var wpfwindow = new Window1();
wpfwindow.WinOwner = this;
wpfwindow.Show();
wpfwindow.WinOwner.Closed += (o, args) =>
{
wpfwindow.Close();
//newWindowTask.Abort();
};
}, DispatcherPriority.Render);
});
newWindowTask.Start();
}
else if (newWindowTask.Status == TaskStatus.RanToCompletion)
{
foreach (var window in WinOwnerCollection)
{
window.Activate();
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
}
浏览器窗口添加此属性:=&gt;
public MainWindow WinOwner
{
get { return _winOwner; }
set
{
_winOwner = value;
if (value is IWinOwnerCollection)
{
((IWinOwnerCollection)value).WinOwnerCollection.Add(this);
}
}
}