首页 / Unity3d / C#

读一读

namespace ActivatorA
{
    class ClassA
    {
        public void Print()
        {
            Console.WriteLine("输出了些东西");
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        Type type = Type.GetType("ActivatorA.ClassA", true);//true表示不存在会引发异常
        ClassA a =  Activator.CreateInstance(type) as ClassA;
        a.Print();

        Console.ReadKey();
    }
}


通过Activator.CreateInstance(命名空间+类名,参数Object[])来实例化实例。


static void Main(string[] args)
{
    Int32 time = 1554454440;
    DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
    DateTime dt = startTime.AddSeconds(time);
    Console.WriteLine(dt.ToString("yyyy-MM-dd HH:mm:ss"));
    Console.ReadLine();
}

DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

2018-04-02 15:37:22


var是用来简写代码的,声明的变量一旦赋值就确定类型了,不允许赋值为其他类型的数据了。可以说,它就是让你省略写变量的类型。

dynamic是动态类型,编辑器在没有运行时都不会知道它是什么类型,所以是不会提示任何消息的,只有当运行时,编辑器通过反射知道类型,调用到不正确的属性和方法时就会出现错误。动态类型,可以修改赋值为其他类型的数据。

static void Main(string[] args)
{
    dynamic a = 100;
    Console.WriteLine(a.GetType());//System.Int32
    dynamic s = "hahaha";
    Console.WriteLine(s.GetType());//System.String
    var t = "asd15";
    Console.WriteLine(t.GetType());//System.String

    s = 1520;
    Console.WriteLine(s.GetType());//System.Int32

    Console.ReadKey();
}

[DllImport("user32.dll")]
public static extern int GetSystemMetrics(int nIndex);

Console.WriteLine(GetSystemMetrics(0));//获取分辨率的宽


DllImport找Dll的目录-》程序当前目录-》System32目录-》环境变量Path所设置的路径


static void Main(string[] args)
{
    System.Net.IPHostEntry iPHostEntry = System.Net.Dns.GetHostEntry("www.chicai.group");
    System.Net.IPAddress[] address = iPHostEntry.AddressList;
    Console.WriteLine(address[0].ToString());

    Console.WriteLine(System.Net.Dns.GetHostAddresses("www.chicai.group")[0]);

    Console.ReadKey();
}

集合类通常不是线程安全的,多个阅读器可以安全的读取集合.但是对集合的任何修改都将为访问集合的所有线程生成不明确的结果.使用以下任何方法都可以令集合类是线程安全的
(1)    使用Synchronized 方法, 则从该类派生包装, 并通过该包装以独占方式访问集合
(2)    如果该类没有Synchronized 方法, 则从该类派生并使用SyncRoot属性实现Synchronized 方法.
(3)    在访问该集合时对SyncRoot属性使用锁定机制
 大家可以看看以下代码:
class Program
{
    static void Main(string[] args)
    {
        Program pg = new Program();
        //写线程
        Thread t1 = new System.Threading.Thread(new ThreadStart(pg.t1fun));
        // 读线程
        Thread t2 = new System.Threading.Thread(new ThreadStart(pg.t2fun));
        //删线程
        Thread t3 = new System.Threading.Thread(new ThreadStart(pg.t3fun));
        t1.Start();
        t2.Start();
        t3.Start();
    }
    ArrayList arraylist = new ArrayList();
    public void t1fun()
    {
        while (true)
        {
            arraylist.Add("t1--写入");
            System.Console.Out.WriteLine("写入");
            System.Threading.Thread.Sleep(1000);
        }
    }
    public void t2fun()
    {
        while (true)
        {
            for (int i = arraylist.Count - 1; i >= 0; i--)
            {
                System.Console.Out.WriteLine("t2读取:" + (string)arraylist[i]);
            }
            System.Threading.Thread.Sleep(1000);
        }
    }
    public void t3fun()
    {
        while (true)
        {
            for (int i = arraylist.Count - 1; i >= 0; i--)
            {
                arraylist.RemoveAt(i);
                System.Console.Out.WriteLine("t3删除:t1" + i.ToString());
            }
            System.Threading.Thread.Sleep(1000);
        }
    }
}
这个测试程序得简单,大家一看就明白了你可以运行一下看看,程序一会就挂了,揭示异常:
未处理的异常: System.ArgumentOutOfRangeException: 索引超出范围。必须为非负值并
小于集合大小。
这就是因为多线程中对共享的集合资源同步引起的

下面是改后的代码:
class Program
{
    static void Main(string[] args)
    {
        Program pg = new Program();
        //写线程
        Thread t1 = new System.Threading.Thread(new ThreadStart(pg.t1fun));
        // 读线程
        Thread t2 = new System.Threading.Thread(new ThreadStart(pg.t2fun));
        //删线程
        Thread t3 = new System.Threading.Thread(new ThreadStart(pg.t3fun));
        t1.Start();
        t2.Start();
        t3.Start();
    }
    ArrayList arraylist = new ArrayList();
    public void t1fun()
    {
        while (true)
        {
            lock (arraylist.SyncRoot)
            {
                arraylist.Add("t1--写入");
            }
            System.Console.Out.WriteLine("写入");
            System.Threading.Thread.Sleep(1000);
        }
    }
    public void t2fun()
    {
        while (true)
        {
            lock (arraylist.SyncRoot)
            {
                for (int i = arraylist.Count - 1; i >= 0; i--)
                {
                    System.Console.Out.WriteLine("t2读取:" + (string)arraylist[i]);
                }
            }
            System.Threading.Thread.Sleep(1000);
        }
    }
    public void t3fun()
    {
        while (true)
        {
            lock (arraylist.SyncRoot)
            {
                for (int i = arraylist.Count - 1; i >= 0; i--)
                {
                    arraylist.RemoveAt(i);
                    System.Console.Out.WriteLine("t3删除:t1" + i.ToString());
                }
            }
            System.Threading.Thread.Sleep(1000);
        }
    }
}

public class CmdHelper
{
    private static string CmdPath = @"C:\Windows\System32\cmd.exe";

    /// <summary>
    /// 执行cmd命令
    /// 多命令请使用批处理命令连接符:
    /// <![CDATA[
    /// &:同时执行两个命令
    /// |:将上一个命令的输出,作为下一个命令的输入
    /// &&:当&&前的命令成功时,才执行&&后的命令
    /// ||:当||前的命令失败时,才执行||后的命令]]>
    /// 其他请百度
    /// </summary>
    /// <param name="cmd"></param>
    /// <param name="output"></param>
    public static void RunCmd(string cmd, out string output)
    {
        cmd = cmd.Trim().TrimEnd('&') + "&exit";//说明:不管命令是否成功均执行exit命令,否则当调用ReadToEnd()方法时,会处于假死状态
        using (Process p = new Process())
        {
            p.StartInfo.FileName = CmdPath;
            p.StartInfo.UseShellExecute = false;        //是否使用操作系统shell启动
            p.StartInfo.RedirectStandardInput = true;   //接受来自调用程序的输入信息
            p.StartInfo.RedirectStandardOutput = true;  //由调用程序获取输出信息
            p.StartInfo.RedirectStandardError = true;   //重定向标准错误输出
            p.StartInfo.CreateNoWindow = true;          //不显示程序窗口
            p.Start();//启动程序

            //向cmd窗口写入命令
            p.StandardInput.WriteLine(cmd);
            p.StandardInput.AutoFlush = true;

            //获取cmd窗口的输出信息
            output = p.StandardOutput.ReadToEnd();
            p.WaitForExit();//等待程序执行完退出进程
            p.Close();
        }
    }
}

public class Base64Helper
{
    public static string encode(string str)
    {
        try
        {
            System.Text.Encoding encode = System.Text.Encoding.ASCII;
            byte[] bytedata = encode.GetBytes(str);
            string strBase64 = Convert.ToBase64String(bytedata, 0, bytedata.Length);
            return strBase64;
        }
        catch
        {
            return null;
        }
    }

    public static string decode(string str)
    {
        try
        {
            byte[] bytedata = Convert.FromBase64String(str);
            string strText = System.Text.ASCIIEncoding.Default.GetString(bytedata);
            return strText;
        }
        catch
        {
            return null;
        }
    }
}

可以将方法前面声明为async表明这个方法有需要异步(分配线程)来执行,所以一定要有await,它表明了它这条语句是需要异步执行的。

using System;
using System.Net;
using System.Threading.Tasks;

namespace Async
{
    class Program
    {
        static void Main(string[] args)
        {
            Task<string> ss = DownLoadStr();
            Console.WriteLine(1);
            Console.WriteLine(ss.Result.Substring(100,100));
            Console.WriteLine(2);

            Console.ReadKey();
        }

        async static Task<string> DownLoadStr()
        {
            Console.WriteLine("异步开始!");
            WebClient wc = new WebClient();
            //await表明下载网页是异步执行的,可以返回到Main中继续执行,同时它也在执行
            string s = await wc.DownloadStringTaskAsync("http://www.chicai.group");
            Console.WriteLine("完成异步方法");
            return s;
        }
    }
}

async的返回值必须是void、Task、Task<>类型的,string表示return(返回)的类型。

但是方法体返回的其实还是Task<T>,可以通过task的Result方法获取到方法中return的结果

获取结果时,如果异步方法没有完成,Main将会等待方法完成,知道获取到结果。

捕获.PNG