Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何为冲突响应生成高阶函数c#_C#_Higher Order Functions - Fatal编程技术网

如何为冲突响应生成高阶函数c#

如何为冲突响应生成高阶函数c#,c#,higher-order-functions,C#,Higher Order Functions,我有一个更新CouchDB数据库的函数,但是如果响应代码冲突,我希望它再次尝试更新,我希望它有3次尝试,我该怎么做 public async Task<HttpResponseMessage> UpdateRecord(Profile latestProfile) { ProfileRecordByUpn profileRecord = await this.GetProfileByUpn(latestProfile); Profile

我有一个更新CouchDB数据库的函数,但是如果响应代码冲突,我希望它再次尝试更新,我希望它有3次尝试,我该怎么做

    public async Task<HttpResponseMessage> UpdateRecord(Profile latestProfile)
    {
        ProfileRecordByUpn profileRecord = await this.GetProfileByUpn(latestProfile);
        Profile oldProfile = profileRecord.Rows.First().Value;

        var client = this.clientFactory.CreateClient(NamedHttpClients.COUCHDB);

        var formatter = new JsonMediaTypeFormatter();
        formatter.SerializerSettings = new JsonSerializerSettings
        {
            Formatting = Formatting.Indented,
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        };

        var query = HttpUtility.ParseQueryString(string.Empty);
        query["rev"] = oldProfile.Rev;

        //Setting the profile Active = true, because as of now we don't have any UI for disabling the account
        latestProfile.Active = oldProfile.Active;

        DateTimeOffset now = DateTimeOffset.Now;
        latestProfile.Created = oldProfile.Created;
        latestProfile.Modified = now;

        //This will check if we the InApp boolean value changed then will set date to Enabled/Disabled
        if (oldProfile.InApp != latestProfile.InApp)
        {                
            if (latestProfile.InApp == true)
            {
                latestProfile.InAppEnabled = now;
                latestProfile.InAppDisabled = oldProfile.InAppDisabled;
            }
            else
            {
                latestProfile.InAppDisabled = now;
                latestProfile.InAppEnabled = oldProfile.InAppEnabled;
            }
        }
        else
        {
            latestProfile.InAppEnabled = oldProfile.InAppEnabled;
            latestProfile.InAppDisabled = oldProfile.InAppDisabled;
        }

        //This will check if we the SMS boolean value changed then will set date to Enabled/Disabled
        if (oldProfile.SMS != latestProfile.SMS)
        {
            if (latestProfile.SMS == true)
            {
                latestProfile.SMSEnabled = now;
                latestProfile.SMSDisabled = oldProfile.SMSDisabled;
            }
            else
            {
                latestProfile.SMSDisabled = now;
                latestProfile.SMSEnabled = oldProfile.SMSEnabled;
            }
        }
        else
        {
            latestProfile.SMSEnabled = oldProfile.SMSEnabled;
            latestProfile.SMSDisabled = oldProfile.SMSDisabled;
        }

        //This will check if we the SMS boolean value changed then will set date to Enabled/Disabled
        if (oldProfile.Email != latestProfile.Email)
        {
            if (latestProfile.Email == true)
            {
                latestProfile.EmailEnabled = now;
                latestProfile.EmailDisabled = oldProfile.EmailDisabled;
            }
            else
            {
                latestProfile.EmailDisabled = now;
                latestProfile.EmailEnabled = oldProfile.EmailEnabled;
            }
        }
        else
        {
            latestProfile.EmailEnabled = oldProfile.EmailEnabled;
            latestProfile.EmailDisabled = oldProfile.EmailDisabled;
        }

        var response = await this.couchDbClient.AuthenticatedQuery(async (c) => {
            return await c.PutAsync($"{API_PROFILES_DB}/{oldProfile.Id.ToString()}?{query}", latestProfile, formatter);
        }, NamedHttpClients.COUCHDB, client);            

        return response;
    }
公共异步任务更新记录(配置文件最新配置文件)
{
ProfileRecordByUpn profileRecord=等待此消息。GetProfileByUpn(latestProfile);
Profile oldProfile=profileRecord.Rows.First().Value;
var client=this.clientFactory.CreateClient(NamedHttpClients.COUCHDB);
var formatter=新的JsonMediaTypeFormatter();
formatter.SerializerSettings=新JsonSerializerSettings
{
格式化=格式化。缩进,
ContractResolver=新的CamelCasePropertyNamesContractResolver()
};
var query=HttpUtility.ParseQueryString(string.Empty);
查询[“rev”]=oldProfile.rev;
//设置profile Active=true,因为到目前为止,我们没有任何用于禁用帐户的UI
latestProfile.Active=oldProfile.Active;
DateTimeOffset now=DateTimeOffset.now;
latestProfile.Created=oldProfile.Created;
latestProfile.Modified=现在;
//这将检查InApp布尔值是否更改,然后将日期设置为启用/禁用
if(oldProfile.InApp!=latestProfile.InApp)
{                
if(latestProfile.InApp==true)
{
latestProfile.inaappeabled=现在;
latestProfile.InAppDisabled=oldProfile.InAppDisabled;
}
其他的
{
latestProfile.InAppDisabled=现在;
latestProfile.InAppeabled=oldProfile.InAppeabled;
}
}
其他的
{
latestProfile.InAppeabled=oldProfile.InAppeabled;
latestProfile.InAppDisabled=oldProfile.InAppDisabled;
}
//这将检查我们是否更改了SMS布尔值,然后将日期设置为启用/禁用
如果(oldProfile.SMS!=latestProfile.SMS)
{
if(latestProfile.SMS==true)
{
latestProfile.SMSEnabled=现在;
latestProfile.SMSDisabled=oldProfile.SMSDisabled;
}
其他的
{
latestProfile.SMSDisabled=now;
latestProfile.SMSEnabled=oldProfile.SMSEnabled;
}
}
其他的
{
latestProfile.SMSEnabled=oldProfile.SMSEnabled;
latestProfile.SMSDisabled=oldProfile.SMSDisabled;
}
//这将检查我们是否更改了SMS布尔值,然后将日期设置为启用/禁用
如果(oldProfile.Email!=latestProfile.Email)
{
if(latestProfile.Email==true)
{
latestProfile.EmailEnabled=现在;
latestProfile.EmailDisabled=oldProfile.EmailDisabled;
}
其他的
{
latestProfile.EmailDisabled=现在;
latestProfile.EmailEnabled=oldProfile.EmailEnabled;
}
}
其他的
{
latestProfile.EmailEnabled=oldProfile.EmailEnabled;
latestProfile.EmailDisabled=oldProfile.EmailDisabled;
}
var response=wait this.couchDbClient.AuthenticatedQuery(异步(c)=>{
返回wait wait c.PutAsync($“{API_PROFILES_DB}/{oldProfile.Id.ToString()}?{query}”,latestProfile,格式化程序);
},名称为dhttpclients.COUCHDB,客户端);
返回响应;
}

那么我将从另一个函数调用这个函数?我是否制作了另一个高阶函数并将此函数作为参数传递给该高阶函数?

C#中的高阶函数是通过将委托作为参数的方法实现的,通常是
操作
函数
委托

在这种情况下,您应该使用一个已建立的库,如

var policy=policy
.HandleResult(r=>r.StatusCode==HttpStatusCode.Conflict)
.RetryAsync(3);
var result=wait policy.ExecuteAsync(()=>UpdateRecord(latestProfile));
更新自己完成(未编译且未测试的代码):

异步任务MyRetry(Func操作) { 对于(整数重试次数=0;重试次数<3;++重试次数) { var result=等待操作(); if(result.StatusCode!=HttpStatusCode.Conflict) 返回结果; } 返回等待操作(); }
上述代码将重试3次,总共4次调用。如果它一直返回
Conflict

是,请为重试逻辑创建一个新函数,并从该包装函数调用该函数。是否创建一个高阶函数的新函数?是吗?是的,你可以做一个普通的高阶函数,接受一个TInput和TOutput函数以及一个int值作为重试计数,并在你需要重试逻辑的地方使用它。你能根据我的代码做一个例子吗?因为我不懂…看一看。我能不用图书馆来做这个吗,波利@斯蒂芬·克利里耶斯;您将编写一个接受
Func
委托的方法,并使其包含重试逻辑。
var policy = Policy
  .HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.Conflict)
  .RetryAsync(3);

var result = await policy.ExecuteAsync(() => UpdateRecord(latestProfile));
async Task<HttpResponseMessage> MyRetry(Func<Task<HttpResponseMessage>> action)
{
  for (int retries = 0; retries < 3; ++retries)
  {
    var result = await action();
    if (result.StatusCode != HttpStatusCode.Conflict)
      return result;
  }
  return await action();
}