第一个WPF学习例子--多线程、任务和UI线程一起使用、方法重载 c#书籍

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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.Diagnostics;/*表示 Windows NT 性能计数器组件。 */
using System.Management;/*获得计算机几乎所有的硬件信息,添加引用[程序集][框架]*/
using System.Windows.Threading;/*调用操作优先级*/
using System.Threading;




namespace Wpf测试
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        private static long 可用内存大小 = 0;
        private int 水平分辨率 = 0;
        private int 垂直分辨率 = 0;
        private double 水平密度X = 96.0;
        private double 垂直密度Y = 96.0;
        private WriteableBitmap 图位图 = null;
        private Task 一, 二, 三, 四;
        private CancellationTokenSource 令牌来源 = null;

        public MainWindow()
        {
            InitializeComponent();
            //ManagementClass 操作系统级 = new ManagementClass("Win32_PhysicalMemory");/*获取总物理内存大小*/
            //ManagementObjectCollection 电源 = 操作系统级.GetInstances();
            //double 获取总物理内存大小 = 0;
            //foreach (ManagementObject 源 in 电源)
            //    获取总物理内存大小 += Int64.Parse(源.Properties["Capacity"].Value.ToString());
            操作系统级 = new ManagementClass("Win32_PerfFormattedData_PerfOS_Memory");/*获取内存可用大小*/
            电源 = cimobject2.GetInstances();
            double 获取内存可用大小 = 0;
            foreach (ManagementObject 源 in 电源)
                获取内存可用大小 += Int64.Parse(源.Properties["AvailableMBytes"].Value.ToString());
            //电源.Dispose();
            //操作系统级.Dispose();
            //PerformanceCounter 纪念品柜台 = new PerformanceCounter("Memory", "Available Bytes");
            //可用内存大小 = Convert.ToInt64(纪念品柜台.NextValue());
            //this.水平分辨率 = (int)获取总物理内存大小 / 20000;
            //if (this.水平分辨率 < 0 || this.水平分辨率 > 15000)
            //    this.水平分辨率 = 15000;
            //this.垂直分辨率 = (int)获取总物理内存大小 / 40000;
            //if (this.垂直分辨率 < 0 || this.垂直分辨率 > 7500)
            //    this.垂直分辨率 = 7500;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            //MessageBox.Show("你好 " + 输入框.Text);
            //if (图位图 == null)
            //    图位图 = new WriteableBitmap(水平分辨率, 垂直分辨率, 水平密度X, 垂直密度Y, PixelFormats.Gray8, null);
            //int 每像素字节 = (图位图.Format.BitsPerPixel + 7) / 8,
            //    大步 = 每像素字节 * 图位图.PixelWidth,
            //    数据大小 = 大步 * 图位图.PixelHeight;
            byte[] 数据 = new byte[数据大小];
            //Stopwatch 观看 = Stopwatch.StartNew();
            生成数据图表(数据);

            Task 第一 = Task.Factory.StartNew(() => 生成数据图表(数据, 0, 水平分辨率 / 4));
            Task 第二 = Task.Factory.StartNew(() => 生成数据图表(数据, 水平分辨率 / 4, 水平分辨率 / 2));
            Task.WaitAll(第一, 第二);

            Task 一 = Task.Factory.StartNew(() => 生成数据图表(数据, 0, 水平分辨率 / 8));
            Task 二 = Task.Factory.StartNew(() => 生成数据图表(数据, 水平分辨率 / 8, 水平分辨率 / 4));
            Task 三 = Task.Factory.StartNew(() => 生成数据图表(数据, 水平分辨率 / 4, 水平分辨率 * 3 / 8));
            Task 四 = Task.Factory.StartNew(() => 生成数据图表(数据, 水平分辨率 * 3 / 8, 水平分辨率 / 2));
            Task.WaitAll(一, 二, 三, 四);

            并行生成数据图表(数据);

            //Task<byte[]> 得到数据任务 = Task<byte[]>.Factory.StartNew(() => 得到的数据对于图(数据大小));
            //byte[] 数据 = 得到数据任务.Result;

            //标题内容.Content = string.Format("时间(ms): {0}", 观看.ElapsedMilliseconds);
            //图位图.WritePixels(new Int32Rect(0, 0, 图位图.PixelWidth, 图位图.PixelHeight), 数据, 大步, 0);
            //显示生成图形.Source = 图位图;

            //Task 任务 = new Task(做绘图工作按钮);
            //任务.ContinueWith(关闭, TaskContinuationOptions.OnlyOnCanceled);
            //任务.Start();

            //Action 做绘图按钮行动工作 = new Action(做绘图工作按钮);
            //做绘图按钮行动工作.BeginInvoke(null, null);



        }
        private void 生成数据图表(byte[] 数据)
        {
            int a = 水平分辨率 / 2, b = a * a, c = 垂直分辨率 / 2;
            for (int x = 0; x < a; x++)
            {
                int s = x * x;
                double p = Math.Sqrt(b - s);
                for (double i = -p; i < p; i += 3)
                {
                    double r = Math.Sqrt(s + i * i) / a;
                    double q = (r - 1) * Math.Sin(24 * r);
                    double y = i / 3 + (q * c);
                    情节XY(数据, x值: (int)(-x + (水平分辨率 / 2)), y值: (int)(y + (垂直分辨率 / 2)));
                    情节XY(数据, x值: (int)(x + (水平分辨率 / 2)), y值: (int)(y + (垂直分辨率 / 2)));
                }
            }
        }
        private void 生成数据图表(byte[] 数据, int 分区启动, int 分区结束)/*函数重载:参数列表不同,由编译器自动选择最佳匹配CancellationToken token*/
        {
            int a = 水平分辨率 / 2, b = a * a, c = 垂直分辨率 / 2;
            for (int x = 分区启动; x < 分区结束; x++)
            {
                int s = x * x;
                double p = Math.Sqrt(b - s);
                for (double i = -p; i < p; i += 3)
                {
                    double r = Math.Sqrt(s + i * i) / a;
                    double q = (r - 1) * Math.Sin(24 * r);
                    double y = i / 3 + (q * c);
                    情节XY(数据, x值: (int)(-x + (水平分辨率 / 2)), y值: (int)(y + (垂直分辨率 / 2)));
                    情节XY(数据, x值: (int)(x + (水平分辨率 / 2)), y值: (int)(y + (垂直分辨率 / 2)));
                }
            }
        }
        private void 生成数据图表(byte[] 数据, int 分区启动, int 分区结束, CancellationToken 令牌)/*函数重载:参数列表不同,由编译器自动选择最佳匹配*/
        {
            int a = 水平分辨率 / 2, b = a * a, c = 垂直分辨率 / 2;
            for (int x = 分区启动; x < 分区结束; x++)
            {
                int s = x * x;
                double p = Math.Sqrt(b - s);
                for (double i = -p; i < p; i += 3)
                {
                    令牌.ThrowIfCancellationRequested();
                    if (令牌.IsCancellationRequested) return;
                    double r = Math.Sqrt(s + i * i) / a;
                    double q = (r - 1) * Math.Sin(24 * r);
                    double y = i / 3 + (q * c);
                    情节XY(数据, x值: (int)(-x + (水平分辨率 / 2)), y值: (int)(y + (垂直分辨率 / 2)));
                    情节XY(数据, x值: (int)(x + (水平分辨率 / 2)), y值: (int)(y + (垂直分辨率 / 2)));
                }
            }
        }
        private void 并行生成数据图表(byte[] 数据)
        { Parallel.For(0, 水平分辨率 / 2, (int x) => { 计算数据(x, 数据); }); }
        private void 计算数据(int x, byte[] 数据)
        {
            int a = 水平分辨率 / 2;
            int b = a * a;
            int c = 垂直分辨率 / 2;
            int s = x * x;
            double p = Math.Sqrt(b - s);
            for (double i = -p; i < p; i += 3)
            {
                double r = Math.Sqrt(s + i * i) / a;
                double q = (r - 1) * Math.Sin(24 * r);
                double y = i / 3 + (q * c);
                情节XY(数据, (int)(-x + (水平分辨率 / 2)), (int)(y + (垂直分辨率 / 2)));
                情节XY(数据, (int)(x + (水平分辨率 / 2)), (int)(y + (垂直分辨率 / 2)));
                //Parallel.Invoke(() => 情节XY(数据, (int)(-x + (水平分辨率 / 2)), (int)(y + (垂直分辨率 / 2))), () => 情节XY(数据, (int)(x + (水平分辨率 / 2)), (int)(y + (垂直分辨率 / 2))));
            }
        }
        private void 情节XY(byte[] 数据, int x值, int y值)
        {
            数据[x值 + y值 * 水平分辨率] = 0xFF;
        }
        private byte[] 得到的数据对于图(int 数据大小)
        {
            byte[] 数据 = new byte[数据大小];
            令牌来源 = new CancellationTokenSource();
            CancellationToken 令牌 = 令牌来源.Token;
            try
            {
                //Task first = Task.Factory.StartNew(() => 生成数据图表(数据, 0, 水平分辨率 / 8));
                //Task second = Task.Factory.StartNew(() => 生成数据图表(数据, 水平分辨率 / 8, 水平分辨率 / 4));
                //Task third = Task.Factory.StartNew(() => 生成数据图表(数据, 水平分辨率 / 4, 水平分辨率 * 3 / 8));
                //Task fourth = Task.Factory.StartNew(() => 生成数据图表(数据, 水平分辨率 * 3 / 8, 水平分辨率 / 2));
                //Task.WaitAll(first, second, third, fourth);

                一 = Task.Factory.StartNew(() => 生成数据图表(数据, 0, 水平分辨率 / 8, 令牌), 令牌);
                二 = Task.Factory.StartNew(() => 生成数据图表(数据, 水平分辨率 / 8, 水平分辨率 / 4, 令牌), 令牌);
                三 = Task.Factory.StartNew(() => 生成数据图表(数据, 水平分辨率 / 4, 水平分辨率 * 3 / 8, 令牌), 令牌);
                四 = Task.Factory.StartNew(() => 生成数据图表(数据, 水平分辨率 * 3 / 8, 水平分辨率 / 2, 令牌), 令牌);
                Task.WaitAll(一, 二, 三, 四);

                //Parallel.Invoke(() => Task.Factory.StartNew(() => 生成数据图表(数据, 0, 水平分辨率 / 8)),
                //    () => Task.Factory.StartNew(() => 生成数据图表(数据, 水平分辨率 / 8, 水平分辨率 / 4)),
                //    () => Task.Factory.StartNew(() => 生成数据图表(数据, 水平分辨率 / 4, 水平分辨率 * 3 / 8)),
                //    () => Task.Factory.StartNew(() => 生成数据图表(数据, 水平分辨率 * 3 / 8, 水平分辨率 / 2)));

                按钮.Dispatcher.Invoke(new Action(() => { 消息.Content = "任务取消"; }), DispatcherPriority.ApplicationIdle);
            }
            catch (AggregateException ae)
            {
                ae.Handle(处理异常);
            }

            String message = String.Format("任务状态 {0}, {1}, {2}, {3}", 一.Status, 二.Status, 三.Status, 四.Status);
            MessageBox.Show(message);

            return 数据;
        }
        private void 做绘图工作按钮(/*任务和UI线程一起使用*/)
        {
            int 每像素字节 = 0, 大步 = 0, 数据大小 = 0;
            按钮.Dispatcher.Invoke(new Action(() =>
            {
                每像素字节 = (图位图.Format.BitsPerPixel + 7) / 8;
                大步 = 每像素字节 * 图位图.PixelWidth;
                数据大小 = 大步 * 图位图.PixelHeight;
            }), DispatcherPriority.ApplicationIdle);

            Stopwatch 观看 = Stopwatch.StartNew();
            Task<byte[]> 得到数据任务 = Task<byte[]>.Factory.StartNew(() => 得到的数据对于图(数据大小));
            byte[] 数据 = 得到数据任务.Result;

            按钮.Dispatcher.Invoke(new Action(() =>
            {
                标题内容.Content = string.Format("时间(ms): {0}", 观看.ElapsedMilliseconds);
                图位图.WritePixels(new Int32Rect(0, 0, 图位图.PixelWidth, 图位图.PixelHeight), 数据, 大步, 0);
                显示生成图形.Source = 图位图;
            }), DispatcherPriority.ApplicationIdle);
        }

        private void 停止_Click(object sender, RoutedEventArgs e)
        {
            if (令牌来源 != null) 令牌来源.Cancel();
        }
        private bool 处理异常(Exception e)
        {
            if (e is TaskCanceledException)
            {
                按钮.Dispatcher.Invoke(new Action(() =>
                {
                    消息.Content = "任务取消";
                }), DispatcherPriority.ApplicationIdle);
                return true;
            }
            else
            {
                return false;
            }
        }

        private void wpf测试_Closed(object sender, EventArgs e)
        {
            关闭(null);
        }
        void 关闭(Task task)
        { wpf测试.Close(); }
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值