我想使用异步调用并行运行多个事务但在任何事务中我想按顺序处理所有任务,因为序列很重要。 我使用异步调用,但它没有帮助,它使整个事务异步发生冲突。
假设我想要并行处理多家公司的数据,但是要按顺序处理公司的数据,我需要产品的产品来获得产品的详细信息,所以首先我必须得到所有产品,然后使用productid对公司获得产品的详细信息。 我无法获得没有productid的产品细节。Task WrappedInTask = Task.Run(() => CompanyAsync(companyId));
public static async Task CompanyAsync(int companyId)
{
string[] products=getAllProducts(compnyId);
for(int i=0; i<products.length>i; i++)
{
//get product detail here using products[i]
}
}
我想完全执行getAllProducts(compnyId),然后执行for循环,如果for循环和getAllProducts(compnyId)方法将异步exicute然后会有冲突。 有任何建议吗
答案 0 :(得分:1)
如果getAllproducts(compnyId)
也是一个异步方法,那么你可以在执行for循环之前等待它完成:
string[] products = await getAllProducts(compnyId);
for(int i = 0; i < products.length; i++)
{
// ...
}
无论如何,我不知道您当前的代码示例是如何编译的。如果getallProducts
实际上是async
方法,则string[] products = getAllProducts(compnyId)
会抛出错误,因为它会返回Task<string[]>
而不是string[]
。
修改强>
你不应该将并行性与异步性混淆。
您似乎希望对列表进行并行迭代。
如果要执行固有的异步操作(例如I / O),通常会使用 async
方法,否则不需要它们。
您可以使用System.Threading.Tasks.Parallel课程来完成任务。
//This will probably create new threads (or not) and will iterate your list concurrently
Parallel.ForEach(dt.Rows, dataRow =>
{
int companyId = //Fetch companyId
Company(companyId);
});
//Code here will execute after each element has been paralelly iterated.
请注意,您的新CompanyAsync
方法签名应更改为:
public static void Company(int companyId);
有关如何使用此方法的进一步参考,请阅读:
答案 1 :(得分:0)
如果你调用一个返回任务或任务的函数,那么你的代码会在任务执行自己的语句时连续执行下一个语句。
直到你输入单词&#34;等待&#34;。如果等待任务,则说:停止执行此代码,直到我正在等待完成执行的任务。
如果您等待一个任务,那么返回是任务函数将返回的TResult,如果它不是异步的话。
现在回到你的问题:如果你想要开始几个任务,但是在你做下一个语句(或者开始下一个任务)之前需要来自已启动任务中的一个或多个的结果,你只需要在执行之前等待任务下一个陈述。
最简单的形式是:
private async Task<int> DoSomethingAsync()
{
int i = await DoXAsync(); // wait for X to finish before starting Y
int j = await DoYAsync(); // wait for Y to finish before starting Z
return await DoZAsync(i, j); // wait until Z finished before returning
}
如果您可以同时运行多个任务,请在需要时开始等待。
private async Task<int> DoSomethingElseAsync()
{
Task<int> taskX = DoXAsync(); // no await, continue with next statement
Task<int> taskY = DoYAsync(); // no await, continue with next statement
// now await until both tasks finished and use the result
// for an await we need a Task or a Task<TResult>
// Task.WaitAll is not suitable: it returns void
// Task.WhenAll returns a Task. we can await for that
await Task.WhenAll( new Task<int>[] {taskX, taskY});
// the results of the task are in Task.Result.
// note that only Task<TResult> has a Result.
// Task is the async version of void return, so no result
return await DoZAsync(taskX.Result, taskY.Result);
}