When you click the "specify" button, the path to the folder with files is indicated, a list of files is obtained and loaded once more into the picturebox and in parallel in the asynchronous method, some data is generated from the image, and after generating them, the second button becomes available. The question is how to write the result of the asynchronous method in the variable Data?

public string[] Images; public string[] Data; public int count = 0; private static readonly HttpClient client = new HttpClient(new HttpClientHandler { AllowAutoRedirect = true, UseCookies = true, CookieContainer = new CookieContainer() }); public void LoadImage() { Image CurrentImage = Image.FromFile(Images[this.count]); pictureBox1.Image = CurrentImage; LoadJSONAsync(CurrentImage); } public async void LoadJSONAsync(Image Image) { /* GET LINE */ string Line = "LINE"; //Нужно записать результат асинхронного вызова в переменную класса Data this.Data[this.count] = Line; button2.Enabled = true; } private void button1_Click(object sender, EventArgs e) { if(folderBrowserDialog1.ShowDialog() == DialogResult.OK) { textBox1.Text = folderBrowserDialog1.SelectedPath; Images = Directory.GetFiles(textBox1.Text); this.count = 0; LoadImage(); } } private void button2_Click(object sender, EventArgs e) { //Работа с this.Data[this.count] } 

enter image description here

  • And what are the difficulties? PS As for me, it is better to do Task with its own logic and the returned result, and leave the record to either the result itself or a separate method. - EvgeniyZ
  • The difficulty is that the Data variable is not visible in the context of the LoadJSONAsync function. And if you make the return value of the LoadJSONAsync function, and wait for completion, the GUI hangs. - LorDo
  • Take a look at this topic: ru.stackoverflow.com/questions/615113/… I’ve thrown 3 solutions there to some extent on a similar issue. Some of the solutions will suit you. For example, through the use of a delegate. - Andrew

1 answer 1

How about this approach?

 public Task<string> LoadImage() { Image CurrentImage = Image.FromFile(Images[this.count]); pictureBox1.Image = CurrentImage; return LoadJSONAsync(CurrentImage); } public async Task<string> LoadJSONAsync(Image Image) { /* GET LINE */ string Line = "LINE"; return Line; } private async void button1_Click(object sender, EventArgs e) { if (folderBrowserDialog1.ShowDialog() == DialogResult.OK) { textBox1.Text = folderBrowserDialog1.SelectedPath; Images = Directory.GetFiles(textBox1.Text); this.count = 0; var line = await LoadImage(); // загрузка строки this.Data[this.count] = line; // делайте с результатом все, что хотите button2.Enabled = true; // UI логика не размазана по методам } } 
  • This approach will cause an error because Data is out of contact button1_Click, there is no Data inside button1_Click. - LorDo
  • @LorDo so you did not show anyone where your variable exists. You brought it in code as a class field - I used it as a class field. If this is not a class field, then change the question code. - tym32167
  • This is the class field, only your solution does not work and throws System.NullReferenceException - LorDo
  • one
    @LorDo everything is perfectly visible inside the method, you apparently just forgot to initialize your field public string[] Data = new string[нужное количество элементов]; - tym32167 1:02
  • one
    @LorDo if you do not know the number of elements in advance, use the List<string> list instead of the string[] array, you can add elements in the list - tym32167