0

При нажатии кнопки "указать", указывается путь к папке с файлами, получается список файлов и по очередной загружается в picturebox и параллельно в асинхронном методе по картинке генерируются некие данные, и после их генерации становится доступна вторая кнопка. Вопрос как записать результат асинхронного метода в переменную 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]
    }

введите сюда описание изображения

Pulanding
  • 695
  • И в чем трудности? P.S. Как по мне, то лучше уж сделать Task со своей логикой и возвращаемым результатом, а запись куда либо самого результата оставить отдельному методу. – EvgeniyZ Nov 18 '18 at 10:31
  • Трудность в том что переменная Data не видна в контексте функции LoadJSONAsync. А если сделать возвращаемое значение функции LoadJSONAsync, и ждать завершения то зависает GUI. – Pulanding Nov 18 '18 at 11:09
  • Загляни вот в эту тему: https://ru.stackoverflow.com/questions/615113/%d0%9f%d0%be%d1%87%d0%b5%d0%bc%d1%83-thread-sleep-%d0%b2%d0%b5%d0%b4%d1%91%d1%82-%d1%81%d0%b5%d0%b1%d1%8f-%d0%bd%d0%b5%d0%bf%d1%80%d0%b0%d0%b2%d0%b8%d0%bb%d1%8c%d0%bd%d0%be-%d0%9a%d0%b0%d0%ba-%d0%bc%d0%bd%d0%b5-%d1%81%d0%b4%d0%b5%d0%bb%d0%b0%d1%82%d1%8c-%d0%b7%d0%b0%d0%b4%d0%b5%d1%80%d0%b6%d0%ba%d1%83-%d0%b8%d0%bb%d0%b8-%d0%b4%d0%bb%d0%b8%d0%bd%d0%bd%d1%8b%d0%b5 Я кидал там 3 решения в некоторй мере подобного вопроса. Часть из решений подойдут и тебе. Например через использование делегата. – Andrew Stop_RU_war_in_UA Nov 18 '18 at 12:07

1 Answers1

1

Как насчет такого подхода?

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 логика не размазана по методам
    }
}
tym32167
  • 32,857
  • Такой подход вызовет ошибку ибо Data находится вне контакте button1_Click, внутри button1_Click не существует Data. – Pulanding Nov 18 '18 at 12:52
  • @LorDo ну так вы не показали же никому, где ваша переменная существует. Вы в коде её привели как поле класса - я использовал её как поле класса. Если это не поле класса - то меняйте код вопроса. – tym32167 Nov 18 '18 at 12:56
  • Это и есть поле класса, только ваше решение не работает и выдает System.NullReferenceException – Pulanding Nov 18 '18 at 12:58
  • Т.к. метод asynс, внутри него не видны переменные класса – Pulanding Nov 18 '18 at 12:58
  • 1
    @LorDo все отлично видно внутри метода, вы, видимо, просто забыли проинициализировать ваше поле public string[] Data = new string[нужное количество элементов]; – tym32167 Nov 18 '18 at 13:02
  • @LorDo и аналогично с public string[] Images = new string[нужное количество элементов]; – tym32167 Nov 18 '18 at 13:03
  • Спасибо! Теперь заработало! А как потупить если заранее не известно сколько потребуется элементов ? Инициализировать просто очень большое число ? – Pulanding Nov 18 '18 at 13:05
  • 1
    @LorDo если не знаете количество элементов заранее, используйте список List<string> вместо массива string[], в списке можно элементы добавлять – tym32167 Nov 18 '18 at 13:07