Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.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# 在Azure批处理中运行Azure Data Factory活动时,应如何处理异步性_C#_Azure_Asynchronous_Azure Data Factory_Azure Batch - Fatal编程技术网

C# 在Azure批处理中运行Azure Data Factory活动时,应如何处理异步性

C# 在Azure批处理中运行Azure Data Factory活动时,应如何处理异步性,c#,azure,asynchronous,azure-data-factory,azure-batch,C#,Azure,Asynchronous,Azure Data Factory,Azure Batch,背景 我稍微简化了这个场景,但这是一般问题 我正在使用Azure数据工厂将来自自定义API的数据摄取到Azure数据仓库中的表中。我使用IDotNetActivity来运行调用API并将数据加载到数据仓库的C代码。该活动在Azure批处理中运行 在活动本身中,在调用自定义API之前,我从Azure Blob存储中的文件加载一个人员列表。 然后为文件中的每个人调用自定义API。 这些调用是依次进行的。 问题是这种方法花费的时间太长。 文件大小可能会增加,因此所需的时间只会变得更糟 我努力提高绩效的

背景

我稍微简化了这个场景,但这是一般问题

我正在使用Azure数据工厂将来自自定义API的数据摄取到Azure数据仓库中的表中。我使用IDotNetActivity来运行调用API并将数据加载到数据仓库的C代码。该活动在Azure批处理中运行

在活动本身中,在调用自定义API之前,我从Azure Blob存储中的文件加载一个人员列表。 然后为文件中的每个人调用自定义API。 这些调用是依次进行的。 问题是这种方法花费的时间太长。 文件大小可能会增加,因此所需的时间只会变得更糟

我努力提高绩效的事情

  • 使API调用异步并分3批调用它们。奇怪的是,它跑得慢了。看起来批处理过程不能很好地处理异步/等待
  • 我们看到的另一个奇怪之处是MoreLinq的批处理命令根本不起作用。我已检查了以下内容的源代码: . 这使用了收益率返回,但我不知道为什么这不起作用,甚至不知道它是否与异步/等待问题有关
主要问题

Azure批处理是否支持异步/等待

其他问题

  • 如果Azure不支持异步/等待,那么解决此问题的更好方法是什么?i、 e.使用作业管理器并旋转更多节点
  • 有人能解释一下为什么MoreLinq的批处理在Azure批处理中不起作用吗? 以下是受影响代码的一个片段:

    List<int> personIds = GetPersonIds(clientAddress, clientUsername, clientPassword);
    var customResults = new List<CustomApiResult>();
    foreach (var personIdsBatch in personIds.Batch(100))
    {
        customResults.AddRange(GetCustomResultsByBatch(address, username, password, personIdsBatch));
    }
    
    List personIds=GetPersonIds(clientAddress、clientUsername、clientPassword);
    var customResults=新列表();
    foreach(personIds.Batch中的变量personIdsBatch(100))
    {
    AddRange(GetCustomResultsByBatch(地址、用户名、密码、PersonidBatch));
    }
    

据我所知,
人形。批量(100)
只需将
人形
批量放入大小(100)的桶中

//方法1
foreach(personIds.Batch中的变量personIdsBatch(100))
{
AddRange(GetCustomResultsByBatch(地址、用户名、密码、PersonidBatch));
}
//方法2
AddRange(GetCustomResultsByBatch(地址、用户名、密码、PersonId));
上述两种方法都会按顺序为每个人调用自定义API,而
method1
添加了处理相同任务的附加逻辑

Azure批处理是否支持异步/等待

根据您的代码,我定义了
IDotNetActivity
实现,如下所示,您可以参考它:

public class MyDotNetActivity : IDotNetActivity
{
    public IDictionary<string, string> Execute(IEnumerable<LinkedService> linkedServices, IEnumerable<Dataset> datasets, Activity activity, IActivityLogger logger)
    {
        return ExecuteAsync(linkedServices, datasets, activity, logger).Result;
    }

    async Task<IDictionary<string, string>> ExecuteAsync(IEnumerable<LinkedService> linkedServices, IEnumerable<Dataset> datasets, Activity activity, IActivityLogger logger)
    {
        List<int> personIds = await GetPersonIds("{clientAddress}", "{clientUsername}", "{clientPassword}");
        var tasks = new List<Task<List<CustomApiResult>>>();
        foreach (var personIdsBatch in personIds.Batch(100))
        {
            tasks.AddRange(GetCustomResultsByBatch("{address}", "{username}", "{password}", "{personIdsBatch}"));
        }

        var taskResults = await Task.WhenAll(tasks);
        List<CustomApiResult> customResults = taskResults.SelectMany(r=>r).ToList();

        //process the custom api results

        return new Dictionary<string, string>();
    }

    async Task<List<CustomApiResult>> GetCustomResultsByBatch(string address, string username, string password, IEnumerable<int> personIdsBatch)
    {
        //Get Custom Results By Batch
        return new List<CustomApiResult>();
    }

    async Task<List<int>> GetPersonIds(string clientAddress, string clientUsername, string clientPassword)
    {
        //load a list of people from a file in Azure Blob storage
        return new List<int>(); 
    }
}
公共类MyDotNetActivity:IDotNetActivity
{
公共IDictionary执行(IEnumerable LinkedService、IEnumerable数据集、活动活动、IActivityLogger)
{
返回ExecuteAsync(链接服务、数据集、活动、记录器);
}
异步任务ExecuteAsync(IEnumerable链接服务、IEnumerable数据集、活动活动、IActivityLogger)
{
List personIds=wait-GetPersonIds(“{clientAddress}”,“{clientUsername}”,“{clientPassword}”);
var tasks=新列表();
foreach(personIds.Batch中的变量personIdsBatch(100))
{
AddRange(GetCustomResultsByBatch(“{address}”、“{username}”、“{password}”、“{personIdsBatch}”);
}
var taskResults=等待任务.WhenAll(任务);
列出customResults=taskResults.SelectMany(r=>r.ToList();
//处理自定义api结果
返回新字典();
}
异步任务GetCustomResultsByBatch(字符串地址、字符串用户名、字符串密码、IEnumerable personIdsBatch)
{
//按批获取自定义结果
返回新列表();
}
异步任务GetPersonId(字符串clientAddress、字符串clientUsername、字符串clientPassword)
{
//从Azure Blob存储中的文件加载人员列表
返回新列表();
}
}
此外,我假设您可以利用以下方法并行执行同步作业:

List<int> personIds = GetPersonIds(clientAddress, clientUsername, clientPassword);
var customResults = new List<CustomApiResult>();
Parallel.ForEach(personIds.Batch(100), 
new ParallelOptions()
{
    MaxDegreeOfParallelism=5
},
(personIdsBatch) =>
{
    var results = GetCustomResultsByBatch(address, username, password, personIdsBatch);
    lock (customResults)
    {
        customResults.AddRange(results);
    }
});
List personIds=GetPersonIds(clientAddress、clientUsername、clientPassword);
var customResults=新列表();
平行。ForEach(personIds.Batch(100),
新选项()
{
MaxDegreeOfParallelism=5
},
(personIdsBatch)=>
{
var results=GetCustomResultsByBatch(地址、用户名、密码、PersonidBatch);
锁定(自定义结果)
{
customResults.AddRange(结果);
}
});

谢谢,布鲁斯,这很有效。MoreLinq批量工程。几个月前这还不起作用。异步/等待代码也可以正常工作。我不知道为什么它以前不起作用。