I need to implement asynchronous work of UI and algorithm in the program. I have already done something similar in the past, but then my algorithm did not return anything, but only worked with files. It looked like this:

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); } } 

In CopyFiles I called RealCopyFiles , which reported progress. Now I need RealCopyFiles to return the value as well. Therefore, in the place where I call CopyFiles I need to assign the result of the RealCopyFiles method RealCopyFiles another variable. But no matter how hard I try, the compiler always swears that it is impossible to do this with asynchronous methods (I don’t mind, just I don’t know how to do it). So how can you reorganize this code, given that RealCopyFiles , and therefore CopyFiles must return a value?

Added flow example:

 public int[,] getCrossCorrelation(byte[,] main_Image, byte[,] template_image) { //.. rowsCompleted++; progressBar1.Value = (int)(((double)rowsCompleted / height) * 100); //.. return crossCorelation; } 

From this method, I would like to bring the processing progress bar in a separate thread. But if we do it by analogy with the previous example, I cannot return the result of this method to an asynchronous method, which, in turn, should also return this result in the place where it is called

What I have at the moment:

 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(); //<-- тут ошибка } 

Error: implicit type conversion "System.Threading.Tasks.Task" to "int [ , ]" is not possible.

  • one
    at a minimum, these functions need to return a value - Grundy
  • What value do you want to return? - Anton Papin
  • @AntonPapin updated post - newbie

3 answers 3

the compiler always swears that this cannot be done with asynchronous methods

It is even possible. Well, or show exactly how you do it and what the compiler says. This is how it works:

 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

Since the method now returns a task, this method also needs to be await :

 private async void btnStart_Click(object sender, EventArgs e) { //.. int[,] crossCorelation = await test(); //<-- тут ошибка } 

Since the whole thing happens in the event handler, and it cannot return the Task , it is highly desirable to wrap the body of the method in try/catch . Why - see here .

  • Strange, I tried in almost the same way, but it didn't work out. Now I will try - newbie
  • I get an error in the place where I call copyFiles and try to pass the result of the execution of copyFiles , which is actually the result of the execution of realCopyFiles , to a variable in the third function. error: неявное преобразование типа "System.Threading.Tasks.Task<int[*,*]>" в "int[*,*]" невозможно. - newbie
  • @newbie code show, or do I need to get my crystal ball? :) - andreycha
  • @andreycha, you don’t need to get it, you don’t need to remove it :-) - Grundy
  • @andreycha Now I will update the question again - newbie

The asynchronous method must return Task , Task<Т> or return nothing ( void ). You can read here https://msdn.microsoft.com/ru-ru/library/mt674882.aspx

 async Task<int> MyMethodAsync() { return 0; } 
  • Well, if I need to return all the same value? - newbie

Can the documentation on msdn help you?

 // Описание асинхроного метода async Task<MyClass> GetMyClassAsync() { MyClass myClassObject = new MyClass(); // Do Somethisng return myClassObject; } // Получение результата MyClass result = await GetMyClassAsync();