在 C# 中异步使用 Web API
Consuming Web API asynchronously in C#
我有一个控制台应用程序 运行 作为调度程序,同样使用 Web API 并且有两个部分,如下所述
- 将文件发布到 API - 我正在将一些文件发送到 API 以获取
文件中的一些信息。
- 从 API- 我收到回复的地方获得回复
从 API 我之前已经发送到 API。
因此流程将如下所示。当调度程序最初运行时,我将向 API 发送一些文件(示例 A、B 和 C)。 API 会花一些时间来处理这些文件。
因此下次调度程序运行时,它将 post 更多文件 D、E、F 等,并将尝试获得 A、B、C 的响应
代码框架如下
static void Main(string[] args)
{
//"starting Posting files to API";
PostDatas(ds);
//"Getting Response from the API";
GetResponseXML(ds);
}
public static void PostDatas(DataSet ds)
{
var client = new HttpClient();
foreach (DataRow dr in ds.Tables[0].Rows)
{
//post the files
var response = client.PostAsync(URL, ReqClass, bsonFormatter).Result;
}
}
public static void GetResponseXML(DataSet ds)
{
var clientResponse = new HttpClient();
foreach (DataRow dr in ds.Tables[1].Rows)
{
//get the response.
var response = clientResponse.PostAsync(URL,ReqClass, bsonFormatter).Result;
}
}
}
这里所有的进程都是同步的,导致时间太长。
我想以异步方式进行 posting 处理和获取响应。 post将多个文件放在一起以及并行获取多个文件的响应
我怎样才能做到这一点?使用线程概念或使用异步和等待概念或 TPL(任务并行库)。我应该在上面的代码中执行哪些更改才能使其异步工作。
请帮忙提供样品。
您需要 create an async version of your Main 然后并行调用每个方法,然后 await
结果。我在这里阻止你的 void Main
因为我想这就是你想要的?你可以在这里添加一个额外的线程池线程,但我怀疑你会从中获得很多好处。我只做了下面的一种方法,因为另一种方法基本相同:
static void Main(string[] args)
{
MainAsync(args).GetAwaiter().GetResult();
}
static async Task MainAsync(string[] args)
{
DataSet ds = new DataSet();
/*logic for getting dataset values.table0 contains posting file details
and Table1 contains details of files which need response*/
//"starting Posting files to API";
await PostDatas(ds);
//"Ending Posting files to API";
//"Getting Response from the API";
await GetResponseXML(ds);
//"Ending Getting Response from the API";
}
public async static Task PostDatas(DataSet ds)
{
var client = new HttpClient();
List<Task<HttpResponseMessage>> tasks = new List<Task<HttpResponseMessage>>();
foreach (DataRow dr in ds.Tables[0].Rows)
{
//post the files
tasks.Add(client.PostAsync(URL, ReqClass, bsonFormatter));
}
await Task.whenAll(tasks);
foreach(var response in tasks)
{
//you can access Result here because you've awaited
//the result of the async call above
HttpResponseMessage message = response.Result;
//etc.
}
}
在 C# 7.0 中,您可以取消 .GetAwaiter().GetResult();
并声明 Main async
; static async Task Main(string[] args)
注意DataSet
is not threadsafe。因此,我不建议您使用此方法更改 class。
如果您不介意在 运行 Getresponse 之前等待您的 post,您还可以添加额外的并行化:
static async Task MainAsync(string[] args)
{
DataSet ds = new DataSet();
/*logic for getting dataset values.table0 contains posting file details
and Table1 contains details of files which need response*/
List<Task> tasks = new List<Task>(2);
//"starting Posting files to API";
tasks.Add(PostDatas(ds));
//"Ending Posting files to API";
//"Getting Response from the API";
tasks.Add(GetResponseXML(ds));
//"Ending Getting Response from the API";
await Task.WhenAll(tasks);
}
我有一个控制台应用程序 运行 作为调度程序,同样使用 Web API 并且有两个部分,如下所述
- 将文件发布到 API - 我正在将一些文件发送到 API 以获取 文件中的一些信息。
- 从 API- 我收到回复的地方获得回复 从 API 我之前已经发送到 API。
因此流程将如下所示。当调度程序最初运行时,我将向 API 发送一些文件(示例 A、B 和 C)。 API 会花一些时间来处理这些文件。
因此下次调度程序运行时,它将 post 更多文件 D、E、F 等,并将尝试获得 A、B、C 的响应
代码框架如下
static void Main(string[] args)
{
//"starting Posting files to API";
PostDatas(ds);
//"Getting Response from the API";
GetResponseXML(ds);
}
public static void PostDatas(DataSet ds)
{
var client = new HttpClient();
foreach (DataRow dr in ds.Tables[0].Rows)
{
//post the files
var response = client.PostAsync(URL, ReqClass, bsonFormatter).Result;
}
}
public static void GetResponseXML(DataSet ds)
{
var clientResponse = new HttpClient();
foreach (DataRow dr in ds.Tables[1].Rows)
{
//get the response.
var response = clientResponse.PostAsync(URL,ReqClass, bsonFormatter).Result;
}
}
}
这里所有的进程都是同步的,导致时间太长。
我想以异步方式进行 posting 处理和获取响应。 post将多个文件放在一起以及并行获取多个文件的响应
我怎样才能做到这一点?使用线程概念或使用异步和等待概念或 TPL(任务并行库)。我应该在上面的代码中执行哪些更改才能使其异步工作。
请帮忙提供样品。
您需要 create an async version of your Main 然后并行调用每个方法,然后 await
结果。我在这里阻止你的 void Main
因为我想这就是你想要的?你可以在这里添加一个额外的线程池线程,但我怀疑你会从中获得很多好处。我只做了下面的一种方法,因为另一种方法基本相同:
static void Main(string[] args)
{
MainAsync(args).GetAwaiter().GetResult();
}
static async Task MainAsync(string[] args)
{
DataSet ds = new DataSet();
/*logic for getting dataset values.table0 contains posting file details
and Table1 contains details of files which need response*/
//"starting Posting files to API";
await PostDatas(ds);
//"Ending Posting files to API";
//"Getting Response from the API";
await GetResponseXML(ds);
//"Ending Getting Response from the API";
}
public async static Task PostDatas(DataSet ds)
{
var client = new HttpClient();
List<Task<HttpResponseMessage>> tasks = new List<Task<HttpResponseMessage>>();
foreach (DataRow dr in ds.Tables[0].Rows)
{
//post the files
tasks.Add(client.PostAsync(URL, ReqClass, bsonFormatter));
}
await Task.whenAll(tasks);
foreach(var response in tasks)
{
//you can access Result here because you've awaited
//the result of the async call above
HttpResponseMessage message = response.Result;
//etc.
}
}
在 C# 7.0 中,您可以取消 .GetAwaiter().GetResult();
并声明 Main async
; static async Task Main(string[] args)
注意DataSet
is not threadsafe。因此,我不建议您使用此方法更改 class。
如果您不介意在 运行 Getresponse 之前等待您的 post,您还可以添加额外的并行化:
static async Task MainAsync(string[] args)
{
DataSet ds = new DataSet();
/*logic for getting dataset values.table0 contains posting file details
and Table1 contains details of files which need response*/
List<Task> tasks = new List<Task>(2);
//"starting Posting files to API";
tasks.Add(PostDatas(ds));
//"Ending Posting files to API";
//"Getting Response from the API";
tasks.Add(GetResponseXML(ds));
//"Ending Getting Response from the API";
await Task.WhenAll(tasks);
}