我有2个实体,我想将一些数据从第二个实体复制到第一个实体,然后我想返回一个简单的字符串,表示成功。我正在使用Polly发出http请求。我打算在json中获取数据然后将其转换为我的Entity模型并执行我可以做的操作,但是同时调用返回不同类型(可能是稍有不同的数据模型)的两个任务时都给出了错误。我在多线程方法中不是很好。 >
public interface IMyRepository
{
string ValidateData(MyData myData);
}
public class MyRepository :IMyRepository
{ private readonly RetryPolicy<HttpResponseMessage> _httpRequestPolicy;
public MyRepository()
{
_httpRequestPolicy = Policy.HandleResult<HttpResponseMessage>(
r => r.StatusCode == HttpStatusCode.InternalServerError)
.WaitAndRetryAsync(3,
retryAttempt => TimeSpan.FromSeconds(retryAttempt), (exception, timeSpan, retryCount, context1) =>
{
var msg = $"Retry {retryCount} implemented with Pollys RetryPolicy " +
$"of {context1.PolicyKey} " +
$"at {context1.ExecutionKey}, " +
$"due to: {exception}.";
});
}
public string ValidateData(MyData MyData)
{
var MyDataOne= Task<MyData>.Factory.StartNew(() => await MyRepository.getProfileOne());
var MyDataTwo= Task<MyData>.Factory.StartNew(() => await MyRepository.getProfileTwo());
//Update some property of MyDataOne on basis of MyDataTwo and return true or fasle in variable **result**
return result;
}
public static async Task<InsuranceCompanyData> getCusomerProfile()
{
var httpClient = GetHttpClient();
string requestEndpoint = "numbers/Get";
HttpResponseMessage httpResponse = await _httpRequestPolicy.ExecuteAsync(() => httpClient.GetAsync(requestEndpoint));
IEnumerable<int> numbers = await httpResponse.Content.ReadAsAsync<IEnumerable<int>>();
return new InsuranceCompanyData();
}
private static HttpClient GetHttpClient()
{
var httpClient = new HttpClient();
httpClient.BaseAddress = new Uri(@"http://localhost:2351/api/");
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
return httpClient;
}
}
public static async Task<MyData> getProfileOne()
{
var httpClient = GetHttpClient();
string requestEndpoint = "/numbers/Get1";
HttpResponseMessage httpResponse = await _httpRequestPolicy.ExecuteAsync(() => httpClient.GetAsync(requestEndpoint));
// IEnumerable<string> data1= await httpResponse.Content.ReadAsAsync<IEnumerable<string>>();
return new MyData();
}
public static async Task<MyData> getProfileTwo()
{
var httpClient = GetHttpClient();
string requestEndpoint = "/numbers/Get2";
HttpResponseMessage httpResponse = await _httpRequestPolicy.ExecuteAsync(() => httpClient.GetAsync(requestEndpoint));
// IEnumerable<string> data2= await httpResponse.Content.ReadAsAsync<IEnumerable<string>>();
return new MyyData();
}
private static HttpClient GetHttpClient()
{
var httpClient = new HttpClient();
httpClient.BaseAddress = new Uri(@"http://localhost:2351/api/");
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
return httpClient;
}
我得到这些错误:
“ await”运算符只能在异步lambda表达式中使用。考虑使用'async'修饰符标记此lambda表达式。
和
非静态字段,方法或属性'MyRepository._httpRequestPolicy'要求对象引用
答案 0 :(得分:1)
请使用Task.Factory.StartNew
:
Task.Run
,它不支持异步lambda(在这里甚至不需要)。
var profileOneTask = Task.Run(() => getProfileOne());
var profileTwoTask = Task.Run(() => getProfileTwo());
请注意,我更改了变量名称以反映它们的实际含义。它们是在某些时候可能会产生结果的任务。它们不是这些操作的结果。
对于第二个问题,应将_httpRequestPolicy
声明为实例成员,而应将其声明为静态成员,以使其在没有实例的情况下可用。但是,如注释中所述,您可以只创建getProfileOne
和getProfileTwo
实例方法。
答案 1 :(得分:0)
为什么不更改ValidateData
签名并将async
关键字添加到方法中?
public async Task<string> ValidateDataAsync(MyData MyData)
{
var task1 = Task<MyData>.Factory.StartNew(() => MyRepository.getProfileOne());
var task2 = Task<MyData>.Factory.StartNew(() => MyRepository.getProfileTwo());
await Task.WhenAll(task1, task2)
//Update some property of MyDataOne on basis of MyDataTwo and return true or fasle in variable **result**
return result;
}
正如@Camilo Terevinto所说,最好使用Task.Run
而不是TaskFactory.StartNew
。