只要在你的代码中写上 App.Current.Shutdown()即可关闭应用程序了。我的机器上只有C#,Vb的用法与C#相同。
只要加一个按钮,在设计器上双击按钮,在事件处理程序中加入上述语句即可。
--------
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
title="MainWindow" Height="350" Width="525">
<Grid>
<Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="10,10,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
</Grid>
</Window>
--------
using System
using System.Collections.Generic
using System.Linq
using System.Text
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
namespace WpfApplication1
{
/// <summary>
/// MainWindow.xaml の相互作用ロジック
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent()
}
private void button1_Click(object sender, RoutedEventArgs e)
{
App.Current.Shutdown()
}
}
}
--------
1. Abort的非及时性使用多线程经常会遇到一个问题,如何停止这个Thread?在WPF中提供了Abort方法,但MSDN却告诉我们:
线程不一定会立即中止,或者根本不中止。 如果线程在作为中止过程的一部分被调用的 finally 块中做非常大量的计算,从而无限期延迟中止 *** 作,则会发生这种情况。
先看下面一段代码:
public partial class MainWindow : Window
{
Thread thread
public MainWindow()
{
InitializeComponent()
Test t = new Test()
thread = new Thread(new ThreadStart(t.Run))
thread.Start()
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Console.WriteLine("abort")
thread.Abort()
}
}
public class Test
{
public void Run()
{
while (true)
{
Console.WriteLine("Running...")
}
}
}
在运行中点击Button,则可能得到的输出如下:
图1
可以看到Abort后线程仍在运行,然后才停止,输出的结果是多变的,有可能Abort之后再无输出,也有可能输出多行,但都能说明一个问题: 使用abort不能立即终止一个thread.
那么到这里,需要先认识一下究竟Abort是什么?
简单来说,Abort是一个标识或者信号,调用它会引发ThreadAbortException,Abort会去请求终止thread,但这不是立即的。
改动一下代码再看看结果:
private void Button_Click(object sender, RoutedEventArgs e)
{
Console.WriteLine("abort")
thread.Abort()
Console.WriteLine(thread.IsAlive)
Console.WriteLine(thread.ThreadState)
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
Console.WriteLine(thread.IsAlive)
Console.WriteLine(thread.ThreadState)
}
图2
点击Button执行Abort后立即输出thread的状态,发现 IsAlive=True , ThreadState=Running ,当然也有可能是 IsAlive=False , ThreadState=Aborted ,因为Abort是不稳定的。然后停一段时间确保thread被终止再点击Button1输出thread的状态,此时 IsAlive=False , ThreadState=Aborted .
2. Abort和Join同时使用的意义
由于abort之后获取到的thread的信息是不稳定的,所以可能会想到用Join,它的作用是:
使用此方法确保线程已终止。 如果线程不终止,则调用方将无限期阻塞。 如果调用 Join 时该线程已终止,此方法将立即返回。
也就是说如果我们使用Abort之后再加上Join,那么Join之后的thread肯定是Aborted.
修改一下Button的代码:
private void Button_Click(object sender, RoutedEventArgs e)
{
Console.WriteLine("abort")
thread.Abort()
thread.Join()
Console.WriteLine(thread.IsAlive)
Console.WriteLine(thread.ThreadState)
}
没有加入Join之前,输出的IsAlive和ThreadState可能是多种情况的,加入之后,输出的一定是 IsAlive=False , ThreadState=Aborted .
需要注意的是Join的作用并不是终止thread,它只是等待thread直到thread执行完成。
3. 如何停止线程
如果考虑让一个thread先停止,然后需要的时候再执行,那么使用abort是很不明智的。一般来说只有当应用程序退出,我们才需要把thread彻底关闭,也就是这时候才用到abort。对于停止线程的需求,可以通过信号来解决:
public partial class MainWindow : Window
{
Thread thread
Test t
public MainWindow()
{
InitializeComponent()
t = new Test()
thread = new Thread(new ThreadStart(t.Run))
thread.Start()
}
private void Button_Click(object sender, RoutedEventArgs e)
{
t.Flag = !t.Flag
}
}
public class Test
{
private bool _flag
public bool Flag
{
set
{
_flag = value
if (_flag == true)
{
Console.WriteLine("flag=true")
}
else
{
Console.WriteLine("flag=false")
}
}
get
{
return _flag
}
}
public void Run()
{
while (true)
{
if (Flag)
{
Console.WriteLine("Running...")
}
}
}
}
上面的例子通过信号量来控制thread中的内容是否执行,在实际应用中,如果一个thread中的内容可能再也不会用到,那么对于这一类情况,使用abort和join;如果这个thread只是临时停止,还会再用到,那么使用信号控制就可以了。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)