我正在使用Twilio C#API将批量消息发送到Twilio API(通常是少量的,但一次可以增长到几千个),为了使流程更快,我开始切换所有内容转到异步调用(以及一些并行的foreaches)。
Twilio API在大部分时间完全同步时工作,但当我将请求更改为异步时,我开始出现大量错误。他们基本上都说:
Connection Error: POST
,内部错误为A task was canceled
。
在进行了一些挖掘之后,我确定Twilio API是在HttpClient
之上构建的,它使用客户端发送所有请求。但是,我无法弄清楚如何使一切正常工作。平均而言,当发送包含3,000多条消息的批次时,大约20%的消息会失败。
我的发送代码非常基本
// async SendTextNotificationsAsync
try
{
var result = MessageResource.Create(
to,
from: new PhoneNumber(PhoneNumber),
body: message);
return result;
}
catch (ApiException ex) // API exception, probably an invalid number.
{
LogTwilioBadNumber(ex, phone);
return null;
}
catch (ApiConnectionException ex) // Connection error, let's reattempt
{
if (tryAttempt < 3)
{
System.Threading.Thread.Sleep(500);
// failed call again
return await SendTextNotificationsAsync(phone, message, tryAttempt + 1);
}
if (tryAttempt >= 3)
{
LogTwilioConnectionException(ex, phone, patientId, tryAttempt);
}
return null;
}
上面是从另一种类似于:
的方法调用的// async void CompleteCampaignsAsync
await Task.Run(() => Parallel.ForEach(campaign.Details, async n =>
{
await com.SendTextNotificationsAsync(to, message);
}));
最后,控制器只需调用类似的东西:
// Don't wait for this to finish, internal processes handle logging
// Will get a time-out error if we wait for this.
await Task.Run(() => cl.CompleteCampaignsAsync()).ConfigureAwait(false);
还有其他几个步骤和层次,因此大致简化了上述步骤和层次。一切都是异步的,等待着一切。唯一真正的例外是主控制器,因为它是一个需要立即启动的长时间运行过程。
在第一种方法中,我尝试了MessageResource.Create
和MessageResource.CreateAsync
。在后者中,我在其无休止的任务流取消错误之前得到了大约80条消息。在前者中,流程运行完成,但大约20%-50%的任务失败。
是否有任何明显错误可以让我纠正这个错误?