「Task.Factory.StartNew で 非同期処理」の方法で、Webページの取得中でもキャンセルなどができるようにしています。
ステータスバーに取得時間を表示します。
 
MainWindow.xaml
<Window x:Class="WpfApplication6.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="250" Width="425">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<DockPanel Grid.Row="0" LastChildFill="True">
<Button DockPanel.Dock="Right" Click="cancelButton_Click">×</Button>
<Button DockPanel.Dock="Right" Click="Button_Click">Get</Button>
<TextBox DockPanel.Dock="Right" Name="urlTextBox" />
</DockPanel>
<TextBox Grid.Row="1" Name="contentTextBox"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto" />
<StatusBar Grid.Row="2">
<TextBlock Name="logTextBlock"
Text="{Binding Path=StatusAndElapsedTime,Mode=OneWay,NotifyOnTargetUpdated=True}"
TargetUpdated="logTextBox_TargetUpdated" />
</StatusBar>
</Grid>
</Window>
MainWindow.xaml.cs
using System.Net.Http;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;
namespace WpfApplication6
{
public partial class MainWindow : Window
{
private HttpClient client = new HttpClient();
private Message message = new Message();
private Task<string> task;
public MainWindow()
{
InitializeComponent();
this.logTextBlock.DataContext = this.message;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
string url = this.urlTextBox.Text;
this.client.CancelPendingRequests();
task = Task.Factory.StartNew(() => GetWebContent(url));
}
private string GetWebContent(string url)
{
this.message.Status = TaskStatus.Running;
Task<string> innerTask = this.client.GetStringAsync(url);
string content = innerTask.Result;
this.message.Status = TaskStatus.RanToCompletion;
return content;
}
private void logTextBox_TargetUpdated(object sender, DataTransferEventArgs e)
{
if (this.message.Status == TaskStatus.RanToCompletion)
{
this.contentTextBox.Text = task.Result;
}
}
private void cancelButton_Click(object sender, RoutedEventArgs e)
{
this.client.CancelPendingRequests();
this.message.Status = TaskStatus.Canceled;
}
}
}
Message.cs
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Threading.Tasks;
namespace WpfApplication6
{
    public class Message : INotifyPropertyChanged
    {
        public Stopwatch Stopwatch { get; set; }
        private TaskStatus status = TaskStatus.Created;
        public TaskStatus Status
        {
            get { return status; }
            set
            {
                if (value != this.status)
                {
                    if (value == TaskStatus.RanToCompletion)
                    {
                        this.Stopwatch.Stop();
                    }
                    else if (value == TaskStatus.Running)
                    {
                        this.Stopwatch.Restart();
                    }
                    this.status = value;
                    NotifyPropertyChanged("Status");
                    NotifyPropertyChanged("StatusAndElapsedTime");
                }
            }
        }
        public string StatusAndElapsedTime
        {
            get
            {
                return this.status + " " +
                    ((this.status == TaskStatus.RanToCompletion) ? this.Stopwatch.Elapsed.ToString() : "");
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
        public Message()
        {
            this.Stopwatch = new Stopwatch();
        }
    }
}
 
0 件のコメント:
コメントを投稿