我有一个简单的过程,它向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);
}
}
}
}
}
答案 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,我无法对此进行测试,但它应该有效。