【问题标题】:Call a method that returns a value every 5 seconds调用每 5 秒返回一个值的方法
【发布时间】:2012-05-16 20:13:41
【问题描述】:

我想调用一个每隔几秒返回一个值的方法。 我曾尝试将TimerelapsedEventandler 一起使用,但在这种情况下该方法的返回类型是无效的。我使用TimerTask 类在Java 中执行相同的任务。

我希望它在 .NET 2.0 中,因为我使用的是 Visual Studio 2005。

以下是我遇到问题的程序。我尝试使用匿名方法,但是这种情况下response的值在匿名方法之外不存在:

public static string Run(string address)
{                     
    string response = "A";
    Timer t = new Timer();
    t.Elapsed += delegate 
    {                         
        response = callURL(address);
        console.writeln(response);
        // The actual response value is printed here                
    };          
    t.Interval = 3000;
    t.Start();                      
    Console.WriteLine("response string is " + response);
    // response string is A

    return response;
}

public static string callURL(string address)
{
    className sig = new ClassName(); 
    String responseBody = sig.getURL(address);

    return responseBody;
}

如何在Run方法中获取response的值并发送给Run方法的调用者?

【问题讨论】:

  • 返回到哪里?计时器可以启动你的方法,但没有人会直接调用它来接收它的结果。
  • 是每5秒调用一次这个方法,还是返回后每5秒才调用一次?即,如果调用时间过长,调用是否可以堆叠?
  • @james:它从另一个类返回给调用者。
  • @DanielA.White:一个方法只能返回两次是什么意思
  • 不过,我认为您缺少的要点是另一个类已经释放了对该方法的控制。计时器在不同的线程上运行。

标签: c# c#-2.0


【解决方案1】:

你可以让你的调用者给带有计时器的类一个回调委托来传回值。

public class YourClass
{
    public static void Run(string address, Action<string> callback)
    {                     
        Timer t = new Timer();
        t.Elapsed += delegate {                         
            var response = callURL(address);

            callback(response);
        };          
        t.Interval = 3000;
        t.Start();
    }
}

public class OtherClass
{
    public void ProcessResponse(string response)
    {
         // do whatever you want here to handle the response...
         // you can write it out, store in a queue, put in a member, etc.
    }

    public void StartItUp()
    {
         YourClass.Run("http://wwww.somewhere.net", ProcessResponse);
    }
}

更新:如果您希望调用者 (OtherClass) 能够取消计时器,您只需将 Action&lt;string&gt; 更改为 Func&lt;string, bool&gt; 并让调用者 (@ 987654325@) 返回一个关于是否停止计时器的布尔值...

public class YourClass
{
    public static void Run(string address, Func<string, bool> callback)
    {                     
        Timer t = new Timer();
        t.Elapsed += delegate {                         
            var response = callURL(address);

            // if callback returns false, cancel timer
            if(!callback(response))
            {
                t.Stop();
            }
        };          
        t.Interval = 3000;
        t.Start();
    }
}

public class OtherClass
{
    public bool ProcessResponse(string response)
    {
         // do whatever you want here to handle the response...
         // you can write it out, store in a queue, put in a member, etc.
         // check result to see if it's a certain value...
         // if it should keep going, return true, otherwise return false
    }

    public void StartItUp()
    {
         YourClass.Run("http://wwww.somewhere.net", ProcessResponse);
    }
}

【讨论】:

  • 哇 james michael hare .. 太快了,太棒了。谢谢你。 :)
  • 随时!当然,您仍然必须编写代码来处理您的响应,但这至少为您提供了框架......
  • 我昨天迷路了。我猜其余的应该不是问题。这是主要的。我试图将代码从 java 转换为 c#。我在这里迷路了。
  • 一个简单的问题。如何在匿名方法中停止计时器?
  • @Bharath:你想什么时候停止?你想在第一个项目之后停止它吗?检索特定结果后? X 分钟后?
【解决方案2】:

创建一个Thread,让线程调用你想要的方法,给线程休眠5秒:

Thread loopThread = new Thread(new ThreadStart(this.MainLoop));
loopThread.Start();

private void MainLoop()
{
     while(true)
     {
         // Do stuff
         Thread.Sleep(5000);
     }
}

【讨论】:

  • 不能用定时器来实现吗?我希望线程调用的方法,在本例中为 MainLoop 返回一个值。
  • 对不起,我失眠了,我讨厌 Sleep() :-)
  • 使用线程是一种更简洁的方式,因为您不会使用计时器停止整个系统?
  • @James:谢谢先生,在做了一些研究和这篇文章stackoverflow.com/questions/1091710/… 之后。我同意 Timmers 在某些地方很有用,就像在这种情况下一样
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-26
  • 2018-05-17
  • 2010-10-24
相关资源
最近更新 更多