您的位置:首页 > 编程语言 > C#

C# 5.0 使用任务调试表TaskScheduler来运行task

2016-02-25 23:11 666 查看
示例效果与winform中this.invoke(new delegete{})跨线程操作资源类似

建立WPF项目,使用4.5框架

mainwindow.xml文件如下

<Window x:Class="TaskSchedulerDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TaskSchedulerDemo"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TextBlock Name="ContentTextBlock" HorizontalAlignment="Left" Margin="44,134,0,0" VerticalAlignment="Top" Width="425" Height="40" />
<Button Content="Sync" HorizontalAlignment="Left" Margin="45,190,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click" />
<Button Content="Async" HorizontalAlignment="Left" Margin="165,190, 0, 0" VerticalAlignment="Top" Width="75" Click="Button_Click_1" />
<Button Content="Async OK" HorizontalAlignment="Left" Margin="285,190,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_2" />
</Grid>
</Window>


mainwindow.xml.cs文件如下

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;
using System.Threading;
using System.Threading.Tasks;

namespace TaskSchedulerDemo
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}

private void Button_Click(object sender, RoutedEventArgs e)
{
//同步运行任务,此时窗体将不作任何响应
ContentTextBlock.Text = string.Empty;
try
{
string result = TaskMethod().Result;
ContentTextBlock.Text = result;
}
catch(Exception ex)
{
ContentTextBlock.Text = ex.InnerException.Message;
}
}

private void Button_Click_1(object sender, RoutedEventArgs e)
{
//异步方式运行任务,窗体可被移动,但抛出子线程访问主线程资源异常
//但此种方式将存在异常的风险
ContentTextBlock.Text = string.Empty;
Mouse.OverrideCursor = Cursors.Wait;
Task<string> task = TaskMethod();
task.ContinueWith(t =>
{
ContentTextBlock.Text = t.Exception.InnerException.Message;
Mouse.OverrideCursor = null;
},
CancellationToken.None,
TaskContinuationOptions.OnlyOnFaulted,
TaskScheduler.FromCurrentSynchronizationContext());

}

private void Button_Click_2(object sender, RoutedEventArgs e)
{
//异步方式运行任务,窗体可被移动,子线程可访问主线程资源
ContentTextBlock.Text = string.Empty;
Mouse.OverrideCursor = Cursors.Wait;
//区别在这
Task<string> task = TaskMethod(TaskScheduler.FromCurrentSynchronizationContext());
task.ContinueWith(t =>
{
Mouse.OverrideCursor = null;
},
CancellationToken.None,
TaskContinuationOptions.None,
TaskScheduler.FromCurrentSynchronizationContext());
}

Task<string> TaskMethod()
{
return TaskMethod(TaskScheduler.Default);
}

Task<string> TaskMethod(TaskScheduler scheduler)
{
//采用task延迟方式可中断延迟,而thread.sleep()则不能
//await Task.Delay(TimeSpan.FromSeconds(5), cancellationTokenSource.Token);
Task delay = Task.Delay(TimeSpan.FromSeconds(5));

return delay.ContinueWith(t =>
{
string str = string.Format("task is running on a thread id {0}. is thread pool thread: {1}",
Thread.CurrentThread.ManagedThreadId,
Thread.CurrentThread.IsThreadPoolThread);
// ContentTextBlock为主线程资源
ContentTextBlock.Text = str;
return str;
}, scheduler);
}
}
}


运行如下:

注意异常提示的区别,中文为程序运行产生,英文为计划输出

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: