程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#收集編程基本之過程和線程詳解

C#收集編程基本之過程和線程詳解

編輯:C#入門知識

C#收集編程基本之過程和線程詳解。本站提示廣大學習愛好者:(C#收集編程基本之過程和線程詳解)文章只能為提供參考,不一定能成為您想要的結果。以下是C#收集編程基本之過程和線程詳解正文


在C#的收集編程中,過程和線程是必備的基本常識,同時也是一個重點,所以我們要好好的控制一下。

一:概念

起首我們要曉得甚麼是”過程”,甚麼是“線程”,好,查一下baike。

過程:是一個具有必定自力功效的法式關於某個數據聚集的一次運動。它是操作體系靜態履行的根本單位,

在傳統的操作體系中,過程既是根本的分派單位,也是根本的履行單位。

線程:是"過程"中某個單一次序的掌握流。

關於這兩個概念,年夜家略微有個印象就好了,避免今後被面試官問到。

二:過程

framework外面對“過程”的根本操作的封裝照樣蠻好的,可以或許知足我們現實開辟中的根本運用。

<1> 獲得過程信息

framework中給我們獲得過程的方法照樣蠻多的,便可以依照Name獲得,也能夠依照ID獲得,也能夠獲得當地和長途的過程信息。

public Process[] GetProcess(string ip = "")
        {
            if (string.IsNullOrEmpty(ip))
                return Process.GetProcesses();

            return Process.GetProcesses(ip);
        }

Process process = Process.GetProcessById(Convert.ToInt32(processID));

<2> 啟動和停滯過程

其實這個也沒啥好說的,不外有一個留意點就是Process中的"kill"和"CloseMainWindow"的差別。

windowMainWindow:  當我們翻開的Process是一個有界面的運用法式時,推舉應用此辦法,它相當於點擊了運用法式的封閉按鈕,是一個有序的終止運用法式的操作,而不像kill那末暴力。  

kill:依據這個單詞估量年夜家都曉得啥意思吧,它的感化就是強迫封閉我們翻開的Process,常常會形成就是我們數據的喪失,所以說在萬不得已的情形下不要應用kill,固然在無圖形界面的運用法式中,kill是獨一可以或許停止Process的一個戰略。

<3> 過程操作的一個演示:

public class ProgessHelper
 {
  //主操作流程
  public static void MainProcess()
  {
   ProgessHelper helper = new ProgessHelper();

   var result = helper.GetProcess();

   helper.ShowProcess(result.Take(10).ToArray());

   Console.Write("\n請輸出您要檢查的過程:");

   helper.ShowProcessSingle(Console.ReadLine());

   Console.Write("\n請輸出您要開啟的法式:\t");

   var name = helper.StartProcess(Console.ReadLine());


   Console.WriteLine("法式曾經開啟,能否封閉?(0,1)");

   if (Console.ReadLine() == "1")
   {
    helper.StopProcess(name);

    Console.WriteLine("封閉勝利。");
   }
  }

  #region 獲得過程
  /// <summary>
/// 獲得過程
/// </summary>
/// <param name="ip"></param>
/// <returns></returns>
  public Process[] GetProcess(string ip = "")
  {
   if (string.IsNullOrEmpty(ip))
    return Process.GetProcesses();

   return Process.GetProcesses(ip);
  }
  #endregion

  #region 檢查過程
  /// <summary>
/// 檢查過程
/// </summary>
/// <param name="process"></param>
  public void ShowProcess(Process[] process)
  {
   Console.WriteLine("過程ID\t過程稱號\t物理內存\t\t啟動時光\t文件名");

   foreach (var p in process)
   {
    try
    {
     Console.WriteLine("{0}\t{1}\t{2}M\t\t{3}\t{4}", p.Id, p.ProcessName.Trim(), p.WorkingSet64 / 1024.0f / 1024.0f,
                   p.StartTime, p.MainModule.FileName);
    }
    catch (Exception ex)
    {
     Console.WriteLine(ex.Message);
    }
   }
  }
  #endregion

  #region 依據ID檢查指定的過程
  /// <summary>
/// 依據ID檢查指定的過程
/// </summary>
/// <param name="processID"></param>
  public void ShowProcessSingle(string processID)
  {
   Process process = Process.GetProcessById(Convert.ToInt32(processID));

   Console.WriteLine("\n\n您要檢查的過程具體信息以下:\n");

   try
   {
    var module = process.MainModule;

    Console.WriteLine("文件名:{0}\n版本{1}\n描敘{2}\n說話:{3}", module.FileName, module.FileVersionInfo.FileVersion,
                   module.FileVersionInfo.FileDescription,
                   module.FileVersionInfo.Language);
   }
   catch (Exception e)
   {
    Console.WriteLine(e.Message);
   }
  }
  #endregion

  #region 過程開啟
  /// <summary>
/// 過程開啟
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
  public string StartProcess(string fileName)
  {
   Process process = new Process();

   process.StartInfo = new ProcessStartInfo(fileName);

   process.Start();

   return process.ProcessName;
  }
  #endregion

  #region 終止過程
  /// <summary>
/// 終止過程
/// </summary>
/// <param name="name"></param>
  public void StopProcess(string name)
  {
   var process = Process.GetProcessesByName(name).FirstOrDefault();

   try
   {
    process.CloseMainWindow();
   }
   catch (Exception ex)
   {
    Console.WriteLine(ex.Message);
   }
  }
  #endregion
 }

快看,PPTV真的被我翻開了,嗯,8錯,Process照樣蠻好玩的。

這裡要留意一點:

我們在59行中加上了Try Catch,這是由於每一個Process都有一個MainModule屬性,但其實不是每個MainModule都能被C#獲得,

如會湧現以下的“謝絕拜訪”。

三: 線程

異樣線程的相干操作也曾經被framework外面的Thread完善的封裝,年夜年夜簡化了我們的任務量,經常使用的操作以下

<1> 啟動線程。
<2> 終止線程。
<3> 暫停線程。
<4> 歸並線程。

這個要說明一下,好比:t1線程在履行進程中須要期待t2履行完能力持續履行,此時我們就要將t2歸並到t1中去,也就是在t1的代碼塊中寫上t2.Join()便可。異樣Join中也能夠加上期待t2履行的時光,不論t2能否履行終了。

<5> 線程同步

估量年夜家也曉得,多線程處理了體系的吞吐量和呼應時光,同時也給我們留下了好比逝世鎖,資本爭用等成績,那末我們若何

處理這些成績呢?呵呵,Anders Hejlsberg 這位老先輩曾經給我們供給了許多的完成同步線程的類,好比Mutex,Monitor,

Interlocked和AutoResetEvent,固然在現實運用中,我們照樣愛好應用簡化版的lock,由於這玩意可以或許使編程簡化,同時使

法式看起來簡練清楚明了。

<6>  異樣我也舉個例子

public class ThreadHelper
 {
  public static void MainThread()
  {

   ThreadHelper helper = new ThreadHelper(100);

   Thread[] thread = new Thread[20];

   for (int i = 0; i < 20; i++)
   {
    thread[i] = new Thread(helper.DoTransactions);

    thread[i].Name = "線程" + i;

   }

   foreach (var single in thread)
   {
    single.Start();
   }
  }

  int balance;

  object obj = new object();

  public ThreadHelper(int balance)
  {
   this.balance = balance;
  }

  #region 取款操作
  /// <summary>
/// 取款操作
/// </summary>
/// <param name="amount"></param>
  public void WithDraw(int amount)
  {
   lock (obj)
   {
    if (balance <= 0)
    {
     Console.WriteLine("哈哈,曾經取完了");
     return;
    }

    if (balance >= amount)
    {
     Console.WriteLine("取款前余額:{0},取款:{1},還殘剩額:{2}", balance, amount, balance - amount);
     balance = balance - amount;
    }
    else
    {
     Console.WriteLine("取款前余額:{0},取款:{1},還殘剩額:{2}", balance, balance, balance = 0);
    }
   }
  }
  #endregion

  #region 主動取款操作
  /// <summary>
/// 主動取款操作
/// </summary>
  public void DoTransactions(object obj)
  {
   int random = new Random().Next(4, 10);

   Thread.Sleep(5000);

   WithDraw(random);
  }
  #endregion
 }

當我們加上lock的時刻一切正常,然則當我們把lock去失落的時刻,看看線程們會有“爭用資本”的景象嗎?,鄙人圖中可以看到,湧現了以下的景象,

固然這不是我想看到的成果,假如在現實運用中會是何等難找的bug。

<8> 線程池

下面的例子中,我創立了20個線程來完成義務,好比在某些現實運用中,Client真個每一個要求Server都須要創立一個線程來處置,

那末當線程許多的時刻其實不是一件功德情,這會招致過度的應用體系資本而耗盡內存,那末天然就會引入“線程池”。

線程池:是一個在後台履行多個義務的聚集,他封裝了我們對線程的根本操作,我們能做的就只需把“進口辦法”丟給線程池就好了。

特色:  線程池有最年夜線程數限制,年夜小在分歧的機械上能否差別的,當池中的線程都是忙碌狀況,後入的辦法就會列隊,直至池中有余暇的線程來處置。

代碼: 修正後以下:

public static void MainThread()
  {

   ThreadHelper helper = new ThreadHelper(100);

   for (int i = 0; i < 20; i++)
   {
    ThreadPool.QueueUserWorkItem(new WaitCallback(helper.DoTransactions));
   }

   //Thread[] thread = new Thread[20];

//for (int i = 0; i < 20; i++)
//{
// thread[i] = new Thread(helper.DoTransactions);

// thread[i].Name = "線程" + i;

//}

//foreach (var single in thread)
//{
// single.Start();
//}
  }

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved