在循环中等待循环以定期检查状态

时间:2015-05-06 16:19:30

标签: c# .net timer wait

我有一个简单的过程,它向API发送请求,等待API返回响应,然后继续此响应。我想避免睡觉主线程,因为这将作为服务运行,我不想阻止启动/停止。

无论如何使用Timer实现这个目的吗?

我的代码类似于:

string RequestID = api.SendRequest(info);
DateTime fiveMinutesFromNow = GetFiveMinutesFromNow();
ApiResponse response = null;

while (response != null && now < fiveMinutesFromNow)
{
     ApiResponse check = api.GetResponse(RequestID);
     if(check.status == "Complete")
     {
          response = check;
          break;
     }else
     {
          //Wait for 3 seconds
     }
}

if(response.status == "Complete")
{
//Continue on
}

谢谢!

编辑:这是我使用AutoResetEvent的当前版本。想法?

class MyClass
{
    private Api _api = new Api();
    private ApiResponse _response = new ApiResponse();
    private EventWaitHandle _waitHandle = new AutoResetEvent(false);
    private string _requestID;
    private readonly Object _criticalSection = new Object();

    void DoStuff()
    {
        Info info = GetInfo();
        _requestID = _api.SendRequest(info); 
        Thread pollingThread = new Thread(PollReutersAPI);
        pollingThread.isBackground = true; 
        pollingThread.Start();

        _waitHandle.Reset();
        if (!_waitHandle.WaitOne(300000))
        {
            pollingThread.Abort();
        }     

        if(_response.status == "Complete")
        {
            //Continue on
        }
    }

    void PollApi()
    {
         while(true)
         {
              ApiResult check = _api.GetResponse(_requestID);
              lock(_criticalSection)
              {
                  if(check.status == "Complete")
                  {
                      _response = check; 
                      _waitHandle.Set();
                      return;
                  }
                  else
                  {
                      Thread.Sleep(3000);
                  }
              }
         }
    }

}

1 个答案:

答案 0 :(得分:0)

尝试启动任务以避免主线程全部在一起。尝试这样的事情:

    private CancellationTokenSource tokenSource;
    private string RequestID;
    ApiResponse response;

    private void form1_Load(object sender, EventArgs e)
    {
        freeUI();
    }

    private void do_stuff()
    {
        RequestID = api.SendRequest(info);
        DateTime fiveMinutesFromNow = GetFiveMinutesFromNow();
        response = null;

        while (response != null && now < fiveMinutesFromNow)
        {
            ApiResponse check = api.GetResponse(RequestID);
            if (check.status == "Complete")
            {
                response = check;
                tokenSource.Cancel();
                break;  // <-- maybe you could remove this since the task was cancelled?
            }
            else
            {
                //Wait for 3 seconds
            }
        }

        if (response.status == "Complete")
        {
            //Continue on
        }
    }

    private async Task freeUI()
    {
        await start_process();

        // do other things
    }

    private Task start_process()
    {
        tokenSource = new CancellationTokenSource();
        token = tokenSource.Token;

        return Task.Factory.StartNew(() =>
        {
            do_stuff();

        }, token);
    }

我使用这种方法重新绑定数据绑定对象或执行大型繁重的任务,我希望UI保持响应。由于我没有你的API,我无法对此进行测试,但它应该有效。