У меня есть асинхронный код для загрузки всех файлов в каталоге в API.Он работает нормально, но я хотел бы отследить, какой файл был загружен и хотел бы войти, чтобы я мог выполнить некоторую проверку статуса.
Я следовал этому руководству , а также этот .Первая создает явные задачи для каждого файла, а вторая ссылка говорит только о количестве оставшихся задач.Я, с другой стороны, хотел бы выяснить, какое задание завершено, распечатать его в журнале и продолжить, пока не будет файлов для загрузки.Для этого я использую компонент «Сценарий» в SSIS.
Это когда две задачи определены специально для 2 файлов.
Task<string> uploadCounterpartFileTask = UploadFiles(year, month, filename_counterparts, accesstoken, path);
Task<string> uploadProductCategoryFileTask = UploadFiles(year, month, filename_productcategories, accesstoken, path);
var allTasks = new List<System.Threading.Tasks.Task> { uploadCounterpartFileTask, uploadProductCategoryFileTask };
while (allTasks.Any())
{
System.Threading.Tasks.Task finished = await System.Threading.Tasks.Task.WhenAny(allTasks);
if (finished == uploadCounterpartFileTask)
{
allTasks.Remove(uploadCounterpartFileTask);
var counterpartFile = await uploadCounterpartFileTask;
}
else if (finished == uploadProductCategoryFileTask)
{
allTasks.Remove(uploadProductCategoryFileTask);
var productCategoriesFile = await uploadProductCategoryFileTask;
}
}
Но я не хочу делать это сейчас, так как яне будет знать, сколько файлов будет в каталоге
Я хотел бы загрузить все файлы в каталог, что-то вроде этого. :-
string[] fileSystemEntries = Directory.GetFileSystemEntries(path);
var tasks = fileSystemEntries.OrderBy(s => s).Select(
fileName => UploadFiles(year, month, Path.GetFileName(fileName), accesstoken, path));
while (tasks.Any())
{
var finished = await System.Threading.Tasks.Task.WhenAny(tasks);
Dts.Events.FireInformation(0, "Script Task for uploading AVRO files", "File Uploaded" + finished.Result, string.Empty, 0, ref fireAgain);
tasks.Remove(finished);
}
Dts.Events.FireInformation(0, "Script Task for uploading AVRO files", "All Files Uploaded", string.Empty, 0, ref fireAgain);
Я использую готово. Результат, потому чтоВ документации MSDN указано, что Result дает задачу, которая была выполнена после whenAny.Я знаю, когда кто-нибудь дает первое, и поэтому я зацикливаюсь (аналогично примерам в MSDN).
Вы видите Dts.Events.FireInformation, поскольку это находится внутри задачи скрипта в SSIS.
Я ожидаю, что в журнале будет что-то вроде.
Загруженный файл: Counterparts.avro
Загруженный файл: ProductCategorties.avro
Загруженный файл: SomeOtherFile.avro
Все файлы загружены.
Но, хотя загрузка файла проходит нормально, ни одно из утверждений не печатается.
Как мне их напечатать?Я просто не хочу получать одно уведомление для всех файлов, мне бы очень хотелось, чтобы у меня был статус загруженного файла.
РЕДАКТИРОВАТЬ: В ответ на один из комментариев приведен код для UploadFiles.,В основном он загружает файл в API и для каждого файла вызывает 3 вызова REST.
private async Task<string> UploadFiles(string year, string month, string filename, string accesstoken, string path)
{
//Initial Put
var method = new HttpMethod("PUT");
string url = String.Format("https://someurl/part1/{0}/{1}/{2}?resource=file&recursive=True", year, month, filename);
var request = new HttpRequestMessage(method, url)
{
Content = null
};
request.Headers.Add("Authorization", "Bearer " + accesstoken);
var initput = await client.SendAsync(request);
//Append Data
url = String.Format("https://someurl/part1/{0}/{1}/{2}?action=append&position=0", year, month, filename);
string SourceFile = path;
var content = new MultipartFormDataContent();
string filenamefullyqualified = path + filename;
Stream fs = System.IO.File.Open(filenamefullyqualified, FileMode.Open, FileAccess.Read, FileShare.None);
content.Add(CreateFileContent(fs, filename, "text/plain"));
method = new HttpMethod("PATCH");
request = new HttpRequestMessage(method, url)
{
Content = content
};
//long filelength = new System.IO.FileInfo(filenamefullyqualified).Length;
request.Headers.Add("Authorization", "Bearer " + accesstoken);
var response = await client.SendAsync(request);
long? position = request.Content.Headers.ContentLength;
//Flush Data
url = String.Format("https://someurl/part1/{0}/{1}/{2}?action=flush&position={3}", year, month, filename, position.ToString());
request = new HttpRequestMessage(method, url)
{
Content = null
};
request.Headers.Add("Authorization", "Bearer " + accesstoken);
response = await client.SendAsync(request);
return filename;
}
РЕДАКТИРОВАТЬ 2: В ответ на комментарий.Пожалуйста, обратите внимание, что это пример кода, который я пытаюсь продемонстрировать эту проблему.
public async void Main()
{
bool fireAgain = true;
HttpClientHandler httpClientHandler = new HttpClientHandler()
{
Proxy = new WebProxy("http://127.0.0.1:8888")
{
UseDefaultCredentials = true,
BypassProxyOnLocal = true
},
UseDefaultCredentials = true
};
string year = "2019";
string month = "02";
string path = "D:\\SomeFolder\\AVRO\\";
client = new HttpClient(handler: httpClientHandler, disposeHandler: true);
string resp = getBearerToken().GetAwaiter().GetResult();
var ser = new JavaScriptSerializer();
var result = ser.DeserializeObject(resp);
Dictionary<string, object> BearerTokenDetails = new Dictionary<string, object>();
BearerTokenDetails = (Dictionary<string, object>)(result);
string accesstoken = BearerTokenDetails["access_token"].ToString();
Dts.Events.FireInformation(0, "Script Task for uploading AVRO files", "Access Code: " + accesstoken, string.Empty, 0, ref fireAgain);
string[] fileSystemEntries = Directory.GetFileSystemEntries(path);
var tasks = fileSystemEntries.OrderBy(s => s).Select(
fileName => UploadFiles(year, month, Path.GetFileName(fileName), accesstoken, path));
await System.Threading.Tasks.Task.WhenAll(tasks);
Dts.Events.FireInformation(0, "Script Task for uploading AVRO files", "All Files Uploaded", string.Empty, 0, ref fireAgain);
}
Вы увидите метод getBearerToken, который я определил как асинхронный, но позже сделал это вызовом Blocked с использованием GetResult, так как это необходимослучиться первым.Кроме того, обратите внимание: первый FireInfo, который вы видите после токена Bearer, сработал только после того, как я сделал блокирующий вызов (GetResult делает это, как я читал).