異世界


2018年9月25日 星期二

內崁IE

public class jgeIE : Object
{
     static public List<SHDocVw.InternetExplorer> IEs = new List<SHDocVw.InternetExplorer>();
     static public void Remove(SHDocVw.InternetExplorer ie)
     {
         int idx = IEs.IndexOf(ie);
         try { IEs[idx].Quit(); }
         catch { }
         try { IEs.RemoveAt(idx); }
         catch { }
     }
     static public void CloseAll()
     {
         for (int i = IEs.Count - 1; i >= 0; i--)
         {
             try { IEs[i].Quit(); }
             catch { }
             try { IEs.RemoveAt(i); }
             catch { }
         }
     }
     // 開心的 瀏覽
     static public void RunBrowser(Form MdiParent, TagObject tg)
     {
         //.. WebBrowser(IP)
         //           
         string _IP = tg.IP;
         string _CAption = tg.Text;
         string arg = String.Format("{0}@{1}", _IP, _CAption);
         // if (findFormBrowser(arg)) { return; }

        FormBrowser fB = new FormBrowser(MdiParent, arg);
         fB.MdiParent = MdiParent;
         fB.Show();
         fB.WindowState = FormWindowState.Maximized;

        fB.Navigate();

        /* 將 FormBrowser 嵌入
         {
             SetParent(fB.Handle, pnlBrowser.Handle);
             //ResizeControlHwnd(fB.Handle, mParnet);
             tabCtlMain.SelectTab(2);
         }*/
     }

    /* 建構式 */
     public jgeIE()
     {
         mBrowser = new SHDocVw.InternetExplorer();
         IEs.Add(mBrowser);

        mBrowser.ToolBar = 0;
         mBrowser.AddressBar = false;
         mBrowser.StatusBar = false;
         mBrowser.MenuBar = false;

        mBrowser.Visible = true;
         mBrowser.OnQuit += new SHDocVw.DWebBrowserEvents2_OnQuitEventHandler(OnQuit);
     }
     public jgeIE(string URL)
     {
         mBrowser = new SHDocVw.InternetExplorer();
         IEs.Add(mBrowser);

        // Win32.SetParent((System.IntPtr)MyBrowser.HWND, pnlWeb.Handle);

        mBrowser.ToolBar = 0;
         mBrowser.AddressBar = false;
         mBrowser.StatusBar = false;
         mBrowser.MenuBar = false;

        //mBrowser.Width = pnlWeb.Width;
         //mBrowser.Height = pnlWeb.Height;
         mBrowser.Top = 0;
         mBrowser.Left = 0;
         mBrowser.Navigate(URL);
         mBrowser.Visible = true;

        mBrowser.OnQuit += new SHDocVw.DWebBrowserEvents2_OnQuitEventHandler(OnQuit);
     }
     /* 欄位 */
     private SHDocVw.InternetExplorer mBrowser;

    /* 屬性 */
     public SHDocVw.InternetExplorer Browser { get { return mBrowser; } set { mBrowser = value; } }
     public int ToolBar { get { return mBrowser.ToolBar; } set { mBrowser.ToolBar = value; } }
     public int Left { get { return mBrowser.Left; } set { mBrowser.Left = value; } }
     public int Top { get { return mBrowser.Top; } set { mBrowser.Top = value; } }
     public int Width { get { return mBrowser.Width; } set { mBrowser.Width = value; } }
     public int Height { get { return mBrowser.Height; } set { mBrowser.Height = value; } }

    public bool AddressBar { get { return mBrowser.AddressBar; } set { mBrowser.AddressBar = value; } }
     public bool StatusBar { get { return mBrowser.StatusBar; } set { mBrowser.StatusBar = value; } }
     public bool MenuBar { get { return mBrowser.MenuBar; } set { mBrowser.MenuBar = value; } }
     public bool Visible { get { return mBrowser.Visible; } set { mBrowser.Visible = value; } }
     public System.IntPtr HWND { get { return (System.IntPtr)mBrowser.HWND; } }

    /* 方法 */
     public void ReSize(int L, int T, int W, int H)
     {
         mBrowser.Top = T;
         mBrowser.Left = L;
         mBrowser.Width = W;
         mBrowser.Height = H;
     }

    /* 事件 */
     public void OnQuit()
     {
         jIE.Remove(this.mBrowser);
     }

}


==============<<  Test   jgeIE class>>=================

private void button2_Click(object sender, EventArgs e)
{
     CreateIE(ref MyBrowser, pnlIE);
     MyBrowser.ReSize(-100,-100,pnlIE.Width,pnlIE.Height);
}


private void Navigate()
{
     Navigate(DefaultURL);
}

private void Navigate(String address)
{
      if (!String.IsNullOrEmpty(address))
      {
          if (!address.StartsWith("http://") && !address.StartsWith("https://"))
          {
              address = "http://" + address;
          }
          try
          {
              Navigate(new Uri(address));
          }
          catch (System.UriFormatException)
          {
              Navigate(new Uri(@"about:blank"));
          }
     }
     else
     {
          Navigate(new Uri(@"about:blank"));
     }
}

private void Navigate(Uri uri)
{
     MyBrowser.Browser.Navigate( uri.ToString() );           
}


#region 內建-IE
     jgeIE MyBrowser;
     private void CreateIE(ref jgeIE browser, Control parent)
     {
      browser = new jgeIE();
      Win32.SetParent(browser.HWND, parent.Handle);

    //MyBrowser.Browser.FullScreen = true;
      MyBrowser.Browser.Left = 0;
      MyBrowser.Browser.Top = 0;
      MyBrowser.Browser.Width = parent.Width;
      MyBrowser.Browser.Height = parent.Height;
     }
     public void jNavigate(string URL)
     {
      //MyBrowser.Browser.Navigate(@"http://www.google.com.tw"); //.. for test
      // MyBrowser.Browser.Navigate(URL);
      if ( (0 == URL.IndexOf("http://", 0))  || (0 == URL.IndexOf("https://", 0)) )
      {
          MyBrowser.Browser.Navigate(URL);
      }
      else
      {
          MyBrowser.Browser.Navigate("http://" + URL);
      }
     }
     private void FormBrowser_FormClosing(object sender, FormClosingEventArgs e)
     {
      jgeIE.CloseAll();
     }
#endregion

2018年8月18日 星期六

HTTP METHOD的不同性質分析:GET,POST和其他4種METHOD的差別

一篇文章解釋HTTP Method

轉貼網址:http://mikuweb.blogspot.tw/2015/10/http-methodgetpost4method.html

HTTP協定中定義了多種不同的method,瀏覽器或是其他程式再進行HTTP連線時,會使用這些method來進行連線並取得回復。
這些method到底有甚麼差別呢?

這裡列舉常見的六種HTTP Method分別是head,get,post,delete,put,patch。
其實還有很多其他得Method,為甚麼要特別提到這六種呢?因為這六種跟網頁的資料有非常大的關係。

先從最常見的get和post說起吧。
一個剛接觸網頁的人或是早期用PHP寫網頁的人常常混用get和post,因為兩者的功能基本上是相同的,而且以前主流是使用網址的Query String和不同的URL來區分功能(比如上傳和搜尋),但是現在愈來愈多網頁用API導向,也就是一個URL負責一個「業務」,對於上傳和瀏覽分別用不同的Method來處理。

舉例來說,我們現在有一個可以留言的留言板,我們通常會使用get來取得現在的留言,而要新增新的留言時,我們會post到這個位置(有點像是問服務生今天的菜單,然後跟同一個服務生點餐)。一些比較早期的網頁則可能混用get和post,把瀏覽留言和新增留言放在不同網址(有點像把領錢和存錢規劃在不同櫃台辦理)。

所以我們現在知道,不同的Method就是對同一件事情做不同的操作。
再來舉服務生點餐的例子,
假設現在我們要點餐,我們必須先知道菜單是甚麼(get),
我們會向服務生點餐(post),
我們想要取消剛才點的餐點(delete),
我們想要重新點一次(put),
我們想要加點甜點和飲料(patch)。

到這裡我們已經提到了主要的Method了(head是取得get的http header而不取得內容,性質上我們可以當作跟get一樣),至於這幾種Method的行為我們可以統整一下:
head:和get一樣,只是head只會取的HTTP header的資料。
get:取得我們想要的資料。
post:新增一項資料。(如果存在會新增一個新的)
put:新增一項資料,如果存在就覆蓋過去。(還是只有一筆資料)。
patch:附加新的資料在已經存在的資料後面。(資料必須已經存在,patch會擴充這項資料)
delete:刪除資料。

說了這麼多,其實這些Method也只是HTTP建議我們這樣做而已,至於網站架設者是不是有遵守又是令外一回事了。(比如說他可以選擇用delete來新增留言)
不過,遵守規定是有好處的,因為瀏覽器會根據不同的Method做不同的事,Google的機器人也會根據連結的不同做不一樣的事(Google有一隻爬蟲會不停更新全世界的網站)。
舉一個例子,現在有一個行事曆網頁,有很多的行事曆事項,旁邊有修改和刪除的按鈕。
如果這些按鈕使用get,Google的爬蟲就會全部去按一遍(他想要知道你的網站的所有內容,他才能建立索引),然後我們的行事曆就被刪光光了!!
如果我們把刪除按鈕改成用delete,Google就不會去按了(他只會按get的連結)。

另外一個例子是,假設現在網路狀況不好,我們用網路ATM轉帳,傳送出去後卻因為網路不穩而瀏覽器沒收到回應,這時如果瀏覽器自動重新整理,就會送出兩筆轉帳要求!!
但是如果轉帳使用post,瀏覽器不但不會自動重新整理,甚至使用者要求重新整理時還會跳出警告訊息。

上面兩個例子告訴我們,不同的Method間接的告訴使用者應該怎麼樣操作這些動作。
這裡有兩個性質,Safe是是否安全,如果會修改資料就是不安全,間接說明是否可以快取(不重複發出請求);Idempotent則是是否可以在不確定有沒有成功送出時重新發出請求。
我們可以整理成以下表格:

image


我們發現,除了get之外的Method都會修改到資料,所以如果我們要寫一支爬蟲,我們就必須要注意,不可以輕易的去觸動除了get以外的Method,因為我們可能會無意間改到資料。
而get,put,delete都可以重新整理,是因為put會覆蓋掉原本的資料(跟服務生說「我」要吃牛排說10次還是只會來一份牛排),delete則是一定會清除資料(跟服務生說我不吃了),所以這3個Method都可以重複呼叫,所以當網路不穩定時瀏覽器可以被允許自動重新整理。

想想如果我們違反這些規定會有甚麼結果。
我們重複和服務生說「一份牛排」(POST)那結果將是我們點了很多份牛排。
我們重複和服務生說「加一份甜點」(patch)那結果就是很多份甜點。

我們架設網站和寫爬蟲時,如果可以儘量遵守這些協定,就可以避免不必要的麻煩。

JSON 資料轉換

image

using System.Windows.Forms;


namespace jgeNHttpTest
{

public partial class Form1 : Form
     {

/* [Jeremy] 測試<> :  JSON 資料轉換 (Class => JSON) */
private void RequestJsonTest(object s, HttpRequestEventArgs e)
{
     List<jUser> users = new List<jUser>();
     jUser jOne = new jUser();
     jOne.Name = "FirstOne";
     users.Add(new jUser());
     users.Add(new jUser());
    users.Add(new jUser());
     users.Add(new jUser());
     string json = JsonConvert.SerializeObject(jOne);
     string jUsers = JsonConvert.SerializeObject(users);

    using (var writer = new StreamWriter(e.Response.OutputStream))
     {
         writer.Write(string.Format("<p>string json =

                   JsonConvert.SerializeObject(jOne) : {0}</p>", json));
         writer.Write(string.Format ("<p>================</p>"));
         writer.Write(string.Format("<p>string jUsers =     

               JsonConvert.SerializeObject(users) : {0}</p>", jUsers));
      }

}


/* [Jeremy] 測試<> :  JSON 資料轉換 (Class => JSON)
private void RequestJsonTest(object s, HttpRequestEventArgs e)
  {
             List<jUser> users = new List<jUser>();
             jUser jOne = new jUser();
             jOne.Name = "FirstOne";
             users.Add(new jUser());
             users.Add(new jUser());
             users.Add(new jUser());
             users.Add(new jUser());
             string json = JsonConvert.SerializeObject(jOne);
             string jUsers = JsonConvert.SerializeObject(users);

            using (var writer = new StreamWriter(e.Response.OutputStream))
             {
                 writer.Write(string.Format("<p>string json = JsonConvert.SerializeObject(jOne) : {0}</p>", json));
                 writer.Write(string.Format("<p>=============================</p>"));
                 writer.Write(string.Format("<p>string jUsers = JsonConvert.SerializeObject(users) : {0}</p>", jUsers));
             }
         }


/* for JSON Data Test */
/* for JSON.NET => Newtonsoft.Json */
public class jUser
{
     public jUser()
     {
         Name = "jason";
         ID = "A1234567890";
         Age = 18;
         Address = "";
         Phone = "(02)111-222-333";
         Counte++;
     }
     public static int Counte { get; set; } //.. static, 不會被轉成 JSON
     public string Name { get; set; }
     public string ID { get; set; }
     public int Age { get; set; }
     public string Address { get; set; }
     public string Phone { get; set; }
}

}


   


2018年8月5日 星期日

使用 Stopwatch 類別來追蹤執行時間

使用 Stopwatch 類別來追蹤執行時間 : 文章出處[https://dotblogs.com.tw/asdtey/2009/10/23/dotnettracetime]


……節錄備忘……


【Stopwatch】

//示範二                                                              
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Star ();                                                          
// code                                                             
System.Threading.Thread.Sleep(100);                                  
sw.Stop();                                                           
Response.Write(sw.Elapsed.TotalSeconds.ToString());                 

平行運算 :PLINQ 的應用

平行運算 (二):PLINQ 的應用 : 文章出處 [https://dotblogs.com.tw/asdtey/2010/05/08/parallelplinq]

……..節錄備忘……

//找出 testData 中包含a 或 包含 abc的字串

resultData = testData.Where(a => a.Contains("a") || a.Contains("abc")).ToList();                            

只要在原本的LINQ語法加上 .AsParallel() 就可以利用平行運算

resultData = testData.AsParallel() .Where(a => a.Contains("a") || a.Contains("abc")).ToList();                         

其中.AsParallel() 並不表示一定會使用平行運算,其執行緒的數目會由 1、2、4、8…來增加,
另外.AsParallel()之後可以接上一個另一個方法 .WithExecutionMode(ParallelExecutionMode.ForceParallelism) ,表示要強迫使用平行運算,
此時程式會像這樣


resultData = testData.AsParallel()                                               
.WithExecutionMode(ParallelExecutionMode.ForceParallelism)
.Where(a => a.Contains("a") || a.Contains("abc")).ToList();  
             

2018年8月4日 星期六

async、 await & Task C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using System.Diagnostics;
using System.Threading;

namespace WindowsFormsApplication1
{
     public partial class Form1 : Form
     {
         public Form1()
         {
             InitializeComponent();
         }

        private void button1_Click(object sender, EventArgs e)
         {
             ThreadMathed(++CallTimes);
             ThreadMathed(++CallTimes);
             ThreadMathed(++CallTimes);
             ThreadMathed(++CallTimes);
             ThreadMathed(++CallTimes);
         }

        /* 主線程 */
         int CallTimes = 0;
         private async void ThreadMathed(int calltimes)
         {
             int Times = calltimes;
             lvAnalysisResult.Items.Add( string.Format("[{0}]:Please wait while analysing the population.", Times));

            try
             {
                 /// 程式寫法[1] : 以另外一個 class 來撰寫 子線程
                 /// ---------------------------------------------------------------------------
                 /// await        new        AnalysisEngine(CallTimes).AnalyzePopulationAsync();
                 /// 非同步等待   建新實體   AnalysisEngine  傳入參數   執行實體內的 Action
                 /// ---------------------------------------------------------------------------
                 //
                 //.. string result = await new AnalysisEngine(CallTimes).AnalyzePopulationAsync();

                /// 程式寫法[2] : 以黏巴達寫法,直接產生子線程區塊
                 /// ---------------------------------------------------------------------------
                 /// await        Task      <string>.    Factory.StartNew
                 /// 非同步等待   建新實體<傳回值型態>   並開始執行
                 ///
                 /// () =>                    { ............. }
                 /// 黏巴達寫法省缺Task物件      Action 的區塊
                 /// ---------------------------------------------------------------------------
                 //
                 string result = await Task<string>.Factory.StartNew
                 (
                     () =>
                         {
                             int Index = Times; //.. 記憶被呼叫的次序

                            //..模擬程式耗時的活動
                             int R = new Random().Next(1, 10000);
                             Thread.Sleep(R);
                            
                             return string.Format("[{0}]:Random Sleep ={1} ms", Index, R);
                         }
                 );

                //.. 印出回傳值
                 lvAnalysisResult.Items.Add(result.ToString());
             }
             catch (System.Exception exp)
             {
                 lvAnalysisResult.Items.Add( exp.Message + Thread.CurrentThread.Name);
             }
         }
     }


     /* 子線程 Class */
     class AnalysisEngine
     {
         private int Index { get; set; } //.. 記憶被呼叫的次序
         public AnalysisEngine(int index) { Index = index; }
        
         public Task<string> AnalyzePopulationAsync()
         {
             Task<string> task = new Task<string>(AnalyzePopulation);
             task.Start();

            return task;
         }

        //..模擬程式耗時的活動
         public string AnalyzePopulation()
         {
             //Sleep is used to simulate the time consuming activity.
             int R = new Random().Next(1, 10000);
             Thread.Sleep(R);
             return string.Format("[{0}]:Random Sleep ={1} ms", Index, R);
         }
     }
}

2018年8月3日 星期五

[SNMP] Float32TC (OCTET STRING) (SIZE(4)) 資料格式轉換

private void TestFloat32TC ()
         {
             /* test : <Float32TC > */
             Float32TC OctSrt32 = new Float32TC();
             OctSrt32.Data = 39222.0F;

            List<byte> bL = OctSrt32.ByteList;
             byte[] bytes = OctSrt32.Bytes;

            listBox1.Items.Add(string.Format("OctSrt16.Data:{0}", OctSrt32.Data));

       }

#region  [SNMP] Float32TC (OCTET STRING) (SIZE(4))
/// <summary>
/// float(32bit) 39222.0
/// MemoryDump =>
///    Byte[]  => Byte[3]=0x47 ,Byte[2]=0x19 ,Byte[1]=0x36 ,Byte[0]=0x00
/// </summary>
public class FloatTC
{
     /* 欄位 */
     protected string m_OctetString = "";

    /* 方法 */
     //.. 將 Float or Double 做 Memory Dump
     public static string FloatToHexString(float source)
     {
         byte[] sourceArray = BitConverter.GetBytes(source);
         var number = BitConverter.ToUInt32(sourceArray, 0);
         string actual = number.ToString("X");
         return actual;
     }
     public static string FloatToHexString(double source)
     {
         byte[] sourceArray = BitConverter.GetBytes(source);
         var number = BitConverter.ToUInt64(sourceArray, 0);
         string actual = number.ToString("X");
         return actual;
     }

    //.. 將 MemoryDumpStr 轉 Float32 or Double64
     public static float HexStringToFloat(string source)
     {
         var number = int.Parse(source, System.Globalization.NumberStyles.AllowHexSpecifier);
         byte[] numberArray = BitConverter.GetBytes(number);
         float actual = BitConverter.ToSingle(numberArray, 0);
         return actual;
     }
     public static double HexStringToDouble(string source)
     {
         var number = int.Parse(source, System.Globalization.NumberStyles.AllowHexSpecifier);
         byte[] numberArray = BitConverter.GetBytes(number);
         double actual = BitConverter.ToSingle(numberArray, 0);
         return actual;
     }

    /* 屬性 */
     public List<byte> ByteList
     {
         get
         {
             var number = int.Parse(m_OctetString, System.Globalization.NumberStyles.AllowHexSpecifier);
             byte[] numberArray = BitConverter.GetBytes(number);
             return numberArray.ToList();
         }
     }
     public byte[] Bytes
     {
         get
         {
             var number = int.Parse(m_OctetString, System.Globalization.NumberStyles.AllowHexSpecifier);
             return BitConverter.GetBytes(number);
         }
     }
}
public class Float32TC : FloatTC
{
     /* 建構式 */
     public Float32TC() { m_OctetString = FloatToHexString(0.0F); }
     public Float32TC(float value) { m_OctetString = FloatToHexString(value); }
     public Float32TC(byte[] value)
     {
         var number = BitConverter.ToUInt32(value, 0);
         m_OctetString = number.ToString("X");
     }
     public Float32TC(List<byte> value)
     {
         var number = BitConverter.ToUInt32(value.ToArray(), 0);
         m_OctetString = number.ToString("X");
     }
     public Float32TC(string value)
     {
         float number = System.Convert.ToSingle(value);
         m_OctetString = number.ToString("X");
     }

    /* 屬性 */
     public float Data
     {
         get
         {
             if (m_OctetString.Length == 8) { return HexStringToFloat(m_OctetString); }
             else { throw (new Exception(string.Format("無法轉換 : [{0}]", m_OctetString))); }
         }
         set
         {
             m_OctetString = FloatToHexString(value);
         }
     }
}
public class Float64TC : FloatTC
{
     /* 建構式 */
     public Float64TC(){m_OctetString = FloatToHexString(0.0);}
     public Float64TC(double value) { m_OctetString = FloatToHexString(value); }
     public Float64TC(byte[] value)
     {
         var number = BitConverter.ToUInt64(value, 0);
         m_OctetString = number.ToString("X");
     }
     public Float64TC(List<byte> value)
     {
         var number = BitConverter.ToUInt64(value.ToArray(), 0);
         m_OctetString = number.ToString("X");
     }
     public Float64TC(string value)
     {
         double number = System.Convert.ToDouble(value);
         m_OctetString = number.ToString("X");
     }


     /* 屬性 */
     public float Data
     {
         get
         {
             if (m_OctetString.Length == 16) { return HexStringToFloat(m_OctetString); }
             else { throw (new Exception(string.Format("無法轉換 : [{0}]", m_OctetString))); }
         }
         set
         {
             m_OctetString = FloatToHexString(value);
         }
     }
}
#endregion