[英]How to call a method of other class from Static void main in c# console application?
[英]How to return to main when timer stopped from other class in c# console application
我有一個帶計時器的班級,如下所示
public class helper
{
Timer timer = new Timer();
private int counter = 0;
private int returnCode = 0;
public int Process()
{
SetTimer();
Console.WriteLine("The application started ");
return counter;
}
public void SetTimer()
{
int optionalWay = 0;
// Create a timer with a two second interval.
timer = new System.Timers.Timer(2000);
// Hook up the Elapsed event for the timer.
timer.Elapsed += (sender, e) => OnTimedEvent(sender, e, optionalWay);
timer.AutoReset = true;
timer.Enabled = true;
}
private void OnTimedEvent(Object source, ElapsedEventArgs e, int optionalWay)
{
counter++;
Console.WriteLine("Timer is ticking");
if (counter == 10)
{
timer.Stop();
timer.Dispose();
returnCode = returnCode + 1;
}
}
}
我下面有這樣的主要功能
public static void Main()
{
helper helper = new helper();
int code = helper.Process();
Console.WriteLine("Main " + code.ToString());
Console.ReadLine();
}
我想做的是在計時器停止時而不是在此之前返回main
,我的計時器類運行正常,主要如下所示
所以main應該等到定時器的結果為1,然后結束進程
該代碼可以正常工作。 helper.Process()
函數內部沒有任何東西可以等待或阻止執行,因此該函數會在執行OnTimedEvent
之前立即返回到main
函數。
解決方法可以通過在helper
類中實現一個事件並在計時器完成其工作之后引發該事件來完成。 並且main
可以收聽該事件並采取相應的行動。
public class helper
{
Timer timer = new Timer();
private int counter = 0;
private int returnCode = 0;
public event EventHandler<int> Done;
...
private void OnTimedEvent(Object source, ElapsedEventArgs e, int optionalWay)
{
counter++;
Console.WriteLine("Timer is ticking");
if (counter == 10)
{
timer.Stop();
timer.Dispose();
returnCode = returnCode + 1;
if (Done != null)
{
Done.Invoke(this, returnCode);
}
}
}
}
並在Program.cs
static void Main(string[] args)
{
helper helper = new helper();
helper.Done += helper_Done;
helper.Process();
Console.ReadLine();
}
static void helper_Done(object sender, int e)
{
Console.WriteLine("Main " + e.ToString());
}
更新資料
Timer類使用ThreadPool中的新線程執行Elapsed
事件處理程序。 因此,它無法返回運行在不同線程上的Main
。 簡而言之:使用計時器無法實現您想做的事情。
這是使用Thread.Sleep()
另一種解決方案,它將滿足您的要求,但是請記住, 不建議使用Thread.Sleep()
這樣的解決方案。
public class helper
{
private int counter = 0;
private int returnCode = 0;
public int Process()
{
Console.WriteLine("The application started ");
StartTimer(2000);
return returnCode;
}
private void StartTimer(int ms)
{
while (counter++ < 10)
{
System.Threading.Thread.Sleep(ms);
Console.WriteLine("Timer is ticking");
}
returnCode = returnCode + 1;
}
}
class Program
{
static void Main(string[] args)
{
helper helper = new helper();
int code = helper.Process();
Console.WriteLine("Main " + code.ToString());
Console.ReadLine();
}
}
再次,這是不使用一個很好的做法Thread.Sleep
為延遲執行和Thread.Sleep
是不准確的比較Timer.Elapsed
。 嘗試更改應用程序的設計,並使用事件或回調函數 。
更改helper
類的Process
函數以接受回調:
public void Process(Action<int> callBack)
{
SetTimer();
Console.WriteLine("The application started ");
if (timer != null)
timer.Disposed += (o, e) => callBack(counter);
}
更改main函數以發送回調:
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
helper helper = new helper();
helper.Process(c => Console.WriteLine("Main " + c.ToString()));
Console.ReadLine();
}
我有兩個選擇,其中一個也是最丑的,就是循環直到計時器停止,基本上是這樣:
public class helper
{
Timer timer = new Timer();
private int counter = 0;
private int returnCode = 0;
private bool timerWorking = false;
public int Process()
{
SetTimer();
Console.WriteLine("The application started ");
while(timerWorking){}
return counter;
}
public void SetTimer()
{
// All the staff you already have
timerWorking = true;
}
private void OnTimedEvent(Object source, ElapsedEventArgs e, int optionalWay)
{
counter++;
Console.WriteLine("Timer is ticking");
if (counter == 10)
{
//All the staff you already have
timerWorking = false;
}
}
}
或者,更優雅的方式是,傳遞或注冊一個到達終點的回調:
public class helper
{
Timer timer = new Timer();
private int counter = 0;
private int returnCode = 0;
Action<int> _doAfterTimerEnds
public void Process(Action<int> doAfterTimerEnds)
{
SetTimer();
_doAfterTimerEnds = doAfterTimerEnds;
Console.WriteLine("The application started ");
}
public void SetTimer()
{
int optionalWay = 0;
// Create a timer with a two second interval.
timer = new System.Timers.Timer(2000);
// Hook up the Elapsed event for the timer.
timer.Elapsed += (sender, e) => OnTimedEvent(sender, e, optionalWay);
timer.AutoReset = true;
timer.Enabled = true;
}
private void OnTimedEvent(Object source, ElapsedEventArgs e, int optionalWay)
{
counter++;
Console.WriteLine("Timer is ticking");
if (counter == 10)
{
timer.Stop();
timer.Dispose();
returnCode = returnCode + 1;
_doAfterTimerEnds(returnCode)
}
}
}
public static void Main()
{
var returnCode = 0;
var helper = new helper();
helper.Process(code => returnCode = code);
while (returnCode != 1) {}
Console.WriteLine("Main " + returnCode);
Console.ReadLine();
}
更新 :我已經測試了最后一個版本,它正在按預期方式工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.