Мне нужно реализовать асинхронную работу UI и алгоритма в своей программе. Я уже делал что-то подобное в прошлом, но тогда мой алгоритм ничего не возвращал, а только работал с файлами. Примерно это выглядело так:
async void CopyFiles(DirectoryInfo dir) {
var len = await Task.Run(() => dir.GetFiles().Length);
var p = new Progress<int>(i => {
progress.Text = i + " файлов из " + len + " отсортировано";
pBar.PerformStep();
});
await Task.Run(() => RealCopyFiles(dir, p));
bDone.Visible = true;
}
void RealCopyFiles(DirectoryInfo dir, IProgress<int> progress) {
var i = 0;
foreach (var k in dir.GetFiles()) {
string month = k.LastWriteTime.ToString("yyyy-MM");
//...
i += 1;
progress.Report(i);
}
}
В CopyFiles
я вызывал RealCopyFiles
, который оповещал о прогрессе.
Теперь мне нужно, что бы RealCopyFiles
ещё и возвращал значение. Следовательно, в месте, где я вызываю CopyFiles
мне нужно присвоить результат работы метода RealCopyFiles
другой переменной. Но как бы я не пытался, компилятор всегда ругается, что нельзя такое делать с асинхронными методами(я как бы и не против, просто по другому я не знаю как это сделать).
То каким образом можно реорганизовать данный код с учётом того, что RealCopyFiles
, а следовательно и CopyFiles
должны возвращать значение?
Добавил поточный пример:
public int[,] getCrossCorrelation(byte[,] main_Image, byte[,] template_image)
{
//..
rowsCompleted++;
progressBar1.Value = (int)(((double)rowsCompleted / height) * 100);
//..
return crossCorelation;
}
С этого метода я хотел бы вынести обработку прогресс бара в отдельный поток. Но если делать это по аналогии с предыдущим примером, я не могу вернуть результат работы этого метода в асинхронный метод, который, в свою очередь, должен так же вернуть этот результат в том месте, где он вызывается
Что имею на данный момент:
public int[,] getCrossCorrelation(byte[,] main_Image, byte[,] template_image, IProgress<int> progress)
{
/..
rowsCompleted++;
currentProgress = (int)(((double)rowsCompleted / height) * 100);
progress.Report(currentProgress);
/..
return crossCorelation;
}
async Task<int[,]> test()
{
var p = new Progress<int>(currentProgress =>
{
progressBar1.Value = currentProgress;
});
var value = await Task.Run(() => getCrossCorrelation(byteImageMain, byteImageTemplate, p));
return value;
}
private void btnStart_Click(object sender, EventArgs e)
{
/..
int[,] crossCorelation = test(); //<-- тут ошибка
}
Ошибка:неявное преобразование типа "System.Threading.Tasks.Task" в "int[,]" невозможно.
компилятор всегда ругается, что нельзя такое делать с асинхронными методами
Очень даже можно. Ну или покажите, как именно вы это делаете и что именно говорит компилятор. Вот так все работает:
int RealCopyFiles(DirectoryInfo dir, IProgress<int> progress)
{
//...
return 42;
}
async Task<int> CopyFiles(DirectoryInfo dir) {
//...
var value = await Task.Run(() => RealCopyFiles(dir, p)); // value = 42
//...
return value;
}
UPD
Поскольку метод теперь возвращает таск, этот метод тоже надо await'ить:
private async void btnStart_Click(object sender, EventArgs e)
{
//..
int[,] crossCorelation = await test(); //<-- тут ошибка
}
Поскольку все это дело происходит в обработчике события, а он не может возвращать Task
, тело метода крайне желательно обернуть в try/catch
. Почему -- смотрите тут.
Асинхронный метод должен возвращать Task
, Task<Т>
либо ничего не возвращать (void
). Почитать можно здесь https://msdn.microsoft.com/ru-ru/library/mt674882.aspx
async Task<int> MyMethodAsync()
{
return 0;
}
Может вам поможет документация на msdn?
// Описание асинхроного метода
async Task<MyClass> GetMyClassAsync()
{
MyClass myClassObject = new MyClass();
// Do Somethisng
return myClassObject;
}
// Получение результата
MyClass result = await GetMyClassAsync();
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Поддерживает ли они подготовку запроса или каждый запрос компилируется по новой?
Учусь C#, читаю чужой код и возник вопрос, что обозначают {0} таким символом, это элемент массива? Вот весь кусок
За счет чего можно достигнуть высокой производительности в DataTable при поиске в ней?
Из названия понятна суть проблемыИнтересует какова временная сложность алгоритма метода AddRange() списка в C#?