參考資料 : 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;}
}
}
沒有留言:
張貼留言