.NET CORE时间异步方法



我有几个异步方法。

其中一个触发了启动进程的CCD_ 1方法。然后,我需要每10分钟对另一个GET方法的结果进行"采样",并检查状态是否已从"挂起"更改为"成功"。

我尝试使用System.Threading.Timer,但没有成功,抱怨我的方法是异步的。

错误CS0407"Task Campaigns.repeat(object("的返回类型Campaigns 错误

这是我的代码:

public async Task waitForCampaignLoadAsync(string Uri)
{
...........
var container = JsonConvert.DeserializeObject<CampaignTempleteStatus>(json);
if(container.status == "pending")
{
var autoEvent = new AutoResetEvent(false);
//The next row triggers the error
var stateTimer = new Timer(repeat, autoEvent, 1000, (1000 * 60 * 10));
//How can I keep repeating this, until (bool isFinished = true)??
}
public async Task repeat(Object stateInfo)
{
if(...)
isFinished = true;
}

另一件事是,如何在repeat函数中传递额外的信息?我需要通过内部ussage的Uri输入?

当异步方法开始变得复杂时,这肯定是出了问题。在大多数情况下,异步代码看起来几乎与添加了await的同步代码相同。

一个简单的轮询循环可以简单到:

public async Task<string> waitForCampaignLoadAsync(string uri)
{
var client=new HttpClient();
for(int i=0;i<30;i++)
{
token.ThrowIfCancellationRequested();
var json = await client.GetStringAsync(uri);
var container = JsonConvert.DeserializeObject<CampaignTempleteStatus>(json);
if (container.status != "pending")
{
return container.status;
}
await Task.Delay(10000); 
}
return "Timed out!";
}

托管线程中的Cancellation解释了如何使用CancellationTokenSource和CancellationToken来取消线程、任务和异步函数。许多异步方法已经提供了接受CancellationToken参数的重载。轮询功能可以修改为接受和检查标记:

public async Task<string> waitForCampaignLoadAsync(string uri,CancellationToken token=default)
{
var client=new HttpClient();
for(int i=0;i<30;i++)
{
var json = await client.GetStringAsync(uri);
var container = JsonConvert.DeserializeObject<CampaignTempleteStatus>(json);
if (container.status != "pending")
{
return container.status;
}
await Task.Delay(10000,token); 
}
return "Timed out!";
}

CancellationTokenSource可用于调用此方法,总超时时间为5分钟:

var cts=new CancellationTokenSource(TimeSpan.FromMinutes(5));
try
{
var result=waitForCampaignLoadAsync(uri,cts.Token);
//Process the result ....
}
catch(OperationCancelledExcepction ex)
{
//Handle the timeout here
}

此代码可以改进。例如,GetStringAsync()不接受取消令牌。不过,该操作可以分为两个步骤,一个步骤是调用GetAsync(),其中包含一个等待服务器发送结果的取消令牌另一个到HttpContent.ReadAsStringAsync()读取响应,例如:

var response=await client.GetAsync(uri,token)
response.EnsureSuccessStatusCode();
var json=await response.Content.ReadAsStringAsync();
...
Timer的第一个参数是TimerCallback委托,它应该返回void
var stateTimer = new Timer(Repeat, autoEvent, 1000, (1000 * 60 * 10));
private void Repeat(object state)
{
....
}

最新更新