在 While 循环中等待以定期检查状态
Wait Inside While Loop to Periodically Check Status
我有一个简单的过程,它向 API 发送请求,等待 API 返回响应,然后继续此响应。我想避免让主线程休眠,因为这将 运行 作为一项服务,我不想阻塞 starts/stops。
有没有办法用定时器实现这个?
我的代码类似于:
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);
}
}
}
}
}
尝试启动一个任务来避开主线程。尝试这样的事情:
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 我无法测试这个,但它应该可以工作。
我有一个简单的过程,它向 API 发送请求,等待 API 返回响应,然后继续此响应。我想避免让主线程休眠,因为这将 运行 作为一项服务,我不想阻塞 starts/stops。
有没有办法用定时器实现这个?
我的代码类似于:
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);
}
}
}
}
}
尝试启动一个任务来避开主线程。尝试这样的事情:
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 我无法测试这个,但它应该可以工作。