2012年11月16日金曜日

スレッドが例外で終了したか調べる

0.5秒ごとにカウントするスレッドで、3回目のカウントで例外を発生させています。
ハンドルしていない例外で終了したスレッドは、Task クラスの IsFaultedプロパティが true になっています。
各々のボタンをクリックすると、対象のスレッドの Task.IsFaulted が true の場合はその例外メッセージを、false の場合は Task.Statusプロパティの内容を表示します。



MainWindow.xaml

<Window x:Class="WpfApplication5.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Height="200" Width="300">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="0">
            <StackPanel Orientation="Horizontal">
                <Button Click="Button_Click_1">状態を見る</Button>
                <TextBlock Text="0.5秒ごとにカウント:" />
                <TextBlock Name="fastTextBlock" Text="{Binding Path=Progress}" />
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <Button Click="Button_Click_2">状態を見る</Button>
                <TextBlock Text="1.0秒ごとにカウント:" />
                <TextBlock Name="slowTextBlock" Text="{Binding Path=Progress}"  />
            </StackPanel>
        </StackPanel>
        <TextBox Name="statusTextBox" Grid.Row="1"
                 ScrollViewer.HorizontalScrollBarVisibility="Auto"
                 ScrollViewer.VerticalScrollBarVisibility="Auto" />
    </Grid>
</Window>

MainWindow.xaml.cs

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;

namespace WpfApplication5
{
    public partial class MainWindow : Window
    {
        private Message message1 = new Message();
        private Message message2 = new Message();
        private Task task1;
        private Task task2;

        public MainWindow()
        {
            InitializeComponent();

            this.fastTextBlock.DataContext = this.message1;
            this.slowTextBlock.DataContext = this.message2;
            task1 = Task.Factory.StartNew(obj => LongRunningMethod1((Message)obj), this.message1);
            task2 = Task.Factory.StartNew(obj => LongRunningMethod2((Message)obj), this.message2);
        }

        private void LongRunningMethod1(Message message)
        {
            for (int i = 0; i < 100; i++)
            {
                message.Progress = i.ToString();
                Thread.Sleep(500);
                if (i == 3)
                {
                    throw new Exception("故意のエラー");
                }
            }
        }

        private void LongRunningMethod2(Message message)
        {
            for (int i = 0; i < 100; i++)
            {
                message.Progress = i.ToString();
                Thread.Sleep(1000);
            }
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            this.statusTextBox.Text = GetStatus(this.task1);
        }

        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            this.statusTextBox.Text = GetStatus(this.task2);
        }

        private string GetStatus(Task task)
        {
            if (task.IsFaulted)
            {
                return task.Exception.ToString();
            }
            else
            {
                return task.Status.ToString();
            }
        }
    }
}

Message.cs

using System;
using System.ComponentModel;

namespace WpfApplication5
{
    public class Message : INotifyPropertyChanged
    {
        private string progress;
        public string Progress
        {
            get { return progress; }
            set
            {
                if (value != this.progress)
                {
                    this.progress = value;
                    NotifyPropertyChanged("Progress");
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
    }
}

0 件のコメント:

コメントを投稿