參考資料 : http://www.codeproject.com/Articles/660482/Insides-Of-Async-Await
在一個 async Methard ( ) 中,程式會在 await 中等待新的線程完成,但主線程不阻塞。
該 async Methard ( ) 可多次進入,產生多個線程同時執行。
/* 主線程 */private async void ThreadMathed()
        {            txtAnalysisResult.Text = "Please wait while analysing the population.";            try            {int result = await new AnalysisEngine().AnalyzePopulationAsync();
txtAnalysisResult.Text = result.ToString();
}
            catch (System.Exception exp)            {txtAnalysisResult.Text = exp.Message + Thread.CurrentThread.Name;
}
}
/* 子線程 Class */class AnalysisEngine    {public Task<int> AnalyzePopulationAsync()
        {Task<int> task = new Task<int>(AnalyzePopulation);
task.Start();
            return task;}
public int AnalyzePopulation()
        {            //Sleep is used to simulate the time consuming activity.Thread.Sleep(10000);
return new Random().Next(1, 5000);
}
}
運用到多線程 SNMP Walk : (該程式需使用 SnmpSharpNet.dll )
/* 主線程 */private async void button2_Click(object sender, EventArgs e)
        {Text = cnt++.ToString();
            NmsDevice dev = new NmsDevice();dev.IP = txtIP.Text;
dev = await Pulling(dev, textBox1.Text);
txtAnalysisResult.Text += dev.PullingOidResult + Environment.NewLine;
}
private async Task<NmsDevice> Pulling(NmsDevice dev, string oid)
        {            NmsDevice Dev = new NmsDevice();            try            {                Dev = await new SNMP_Walk(dev, oid).OidPullingAsync();}
            catch (System.Exception exp)            {                //txtAnalysisResult.Text = exp.Message + Thread.CurrentThread.Name;Dev.PullingOidResult = string.Format("No response received from SNMP agent.{0}", Environment.NewLine);
}
            return Dev;}
子線程物件:
public class SNMP_Walk
 {     /* 建構式 */public SNMP_Walk(NmsDevice dev, string oid)
     {mDevice = dev;
OID = oid;
}
     /* 屬性 */private NmsDevice mDevice = new NmsDevice();
private string OID { get; set; }
     /* 方法 */     public Task<NmsDevice> OidPullingAsync()     {         /* 一般程式寫法 */         //Task<NmsDevice> task = new Task<NmsDevice>(SnmpWalk);         //task.Start();         /* 黏巴達 語法 */         //Task<NmsDevice> task = Task<NmsDevice>.Factory.StartNew(() => { return SnmpWalk(); });         //return task;         /* 匿名方式 黏巴達 語法*/return Task<NmsDevice>.Factory.StartNew(() => { return SnmpWalk(); });
}
     private NmsDevice SnmpWalk()     {         string IP = mDevice.IP;List<string> list = new List<string>();
list = SnmpWalkList(IP, OID);
         /* 串接回傳值 */         mDevice.PullingOidResult = "";foreach (string ss in list)
         {mDevice.PullingOidResult += string.Format("{0}{1}", ss, Environment.NewLine);
}
         return mDevice;}
private List<string> SnmpWalkList(string IP, string oid)
     {List<string> list = new List<string>();
         try         {             // SNMP community nameOctetString community = new OctetString("public");
             // Define agent parameters class             AgentParameters param = new AgentParameters(community);             // Set SNMP version to 1param.Version = SnmpVersion.Ver1;
             // Construct the agent address object             // IpAddress class is easy to use here because             //  it will try to resolve constructor parameter if it doesn't             //  parse to an IP address             IpAddress agent = new IpAddress(IP);             // Construct target             UdpTarget target = new UdpTarget((IPAddress)agent, 161, 2000, 1);             // Define Oid that is the root of the MIB             //  tree you wish to retrieveOid rootOid = new Oid(oid.Replace("\"", "")); // ifDescr
             // This Oid represents last Oid returned by             //  the SNMP agentOid lastOid = (Oid)rootOid.Clone();
             // Pdu class used for all requests             Pdu pdu = new Pdu(PduType.GetNext);             #region Loop through resultswhile (lastOid != null)
             {                 // When Pdu class is first constructed, RequestId is set to a random value                 // that needs to be incremented on subsequent requests made using the                 // same instance of the Pdu class.                 if (pdu.RequestId != 0)                 {pdu.RequestId += 1;
}
                 // Clear Oids from the Pdu class.pdu.VbList.Clear();
                 // Initialize request PDU with the last retrieved Oidpdu.VbList.Add(lastOid);
                 // Make SNMP requestSnmpV1Packet result = (SnmpV1Packet)target.Request(pdu, param);
                 // You should catch exceptions in the Request if using in real application.                 // If result is null then agent didn't reply or we couldn't parse the reply.if (result != null)
                 {                     // ErrorStatus other then 0 is an error returned by                      // the Agent - see SnmpConstants for error definitions                     if (result.Pdu.ErrorStatus != 0)                     {                         // agent reported an error with the requestConsole.WriteLine(string.Format("Error in SNMP reply. Error {0} index {1}",
result.Pdu.ErrorStatus,
result.Pdu.ErrorIndex));
                         lastOid = null;                         break;}
                     else                     {                         // Walk through returned variable bindingsforeach (Vb v in result.Pdu.VbList)
                         {                             // Check that retrieved Oid is "child" of the root OID                             if (rootOid.IsRootOf(v.Oid))                             {                                 //listBox1.Items.Add(string.Format("{0} ({1}): {2}",                                 //    v.Oid.ToString(),                                 //    SnmpConstants.GetTypeName(v.Value.Type),                                 //    v.Value.ToString()) );list.Add(string.Format("{0}{1}", v.Value.ToString(), Environment.NewLine));
lastOid = v.Oid;
}
                             else                             {                                 // we have reached the end of the requested                                 // MIB tree. Set lastOid to null and exit loop                                 lastOid = null;}
}
}
}
                 else                 {list.Add(string.Format("No response received from SNMP agent.{0}", Environment.NewLine));
}
}
             #endregiontarget.Close();
             return list;}
         catch (Exception ex)         {list.Add(string.Format("No response received from SNMP agent.{0}", Environment.NewLine));
             return list;}
}
}
沒有留言:
張貼留言