Еще одно ожидание, которое не ждет - PullRequest
0 голосов
/ 11 сентября 2018

Обычно я не пишу, я читаю и нахожу свои ответы.

Но на этот раз, несмотря на то, что я нашел дюжину постов о проблеме async / await, похоже, решение для моего случая не сработало (или я, по крайней мере, не понял).

Мой код очень длинный, поэтому я не помещаю его здесь целиком, но это выглядит так: у меня есть задача, которая пишет вбаза данных:

public async Task WatchSpool(Button buttonSend)
{
    LoadOptions();
    //SpoolWatcher spoolWatcher = new SpoolWatcher(this, buttonSend);
    SpoolWatcher spoolWatcher = new SpoolWatcher(this);
    spoolWatcher.OnSpoolWatcherException += OnSpoolWatcherException;
    Task thread = new Task(spoolWatcher.Run);
    spoolWatcherMustStop = false;
    thread.Start();
    //spoolWatcher.Run();
}

Затем еще одна, которая подсчитывает количество записей в конкретной таблице в базе данных:

public int CountWaitingRecords(string table)
{
    int WaitingRecords = 0;
    try
    {
        using (SqliteConnection connexion = new SqliteConnection("Filename = spool.db"))
        {
            connexion.Open();
            using (SqliteCommand cmd = new SqliteCommand("SELECT COUNT(*) AS Count FROM " + table, connexion))
            {
                SqliteDataReader rs = cmd.ExecuteReader();
                rs.Read();

                WaitingRecords = rs.GetInt32(rs.GetOrdinal("Count"));

                rs.Dispose();
                cmd.Dispose();
                connexion.Dispose();
            }
        }
    }
    catch(Exception ex)
    {
        return -1;
    }
    return WaitingRecords;
}

И они оба называются здесь:

private async void buttonSendSelectedItems_Click(object sender, RoutedEventArgs e)
{
    try
    {
        //things doing fine here…

        //Start spoolWatcher
        batigest = new Batigest(localFolder + "\\spool.db");
        batigest.OnSpoolWatcherException += new OnSpoolWatcherExceptionHandler(batigest_OnSpoolWatcherException);
        //Alternative code
        //Task.Run(() => batigest.WatchSpool(Envoyer)).Wait();
        //Actual code
        Task task = batigest.WatchSpool(Envoyer);
        await task;
        //Another alternative code
        //task.Wait();

        //Here I count how many rows I've in my table
        LocalDB localDB = new LocalDB(localFolder.Path.ToString() + "\\spool.db");
        int count = localDB.CountWaitingRecords("MouvementStock");
        if (count > 0)
        {
            Envoyer.Content = "Envoyer (" + count + ")";
            Envoyer.IsEnabled = true;
        }
        else
        {
            Envoyer.Content = "Envoyé!";
        }

        //Other things doing fine here…

    }
    catch (Exception ex)
    {
        Envoyer.IsEnabled = true;
        Envoyer.Content = "Erreur!";
        InterpretException("InventoryView2.buttonSendSelectedItems_Click()", ex);
    }
}

Дело в том, что прежде чем я начну считать, сколько строк в моей базе данных, я должен подождать, чтобы эта задача была выполнена.Но я не могу добиться успеха.Поэтому, если кто-нибудь скажет мне, что я делаю неправильно, я буду признателен.

1 Ответ

0 голосов
/ 11 сентября 2018

У этого фрагмента кода есть некоторые проблемы:

public async Task WatchSpool(Button buttonSend)
{
    SpoolWatcher spoolWatcher = new SpoolWatcher(this);
    spoolWatcher.OnSpoolWatcherException += OnSpoolWatcherException;
    Task thread = new Task(spoolWatcher.Run);
    thread.Start();
}

Прежде всего, Task не является потоком, поэтому его именование как таковое вводит в заблуждение и неправильно.

Во-вторых, конструктора Task следует избегать.Предполагая, что SpoolWatcher.Run не является Task, вы должны использовать Task.Run:

Task runner = Task.Run(() => spoolWatcher.Run());

В-третьих, и самое главное, вы не await ожидаете его завершения, поэтому WatchSpoolвернется почти сразу.

public async Task WatchSpool(Button buttonSend)
{
    SpoolWatcher spoolWatcher = new SpoolWatcher(this);
    spoolWatcher.OnSpoolWatcherException += OnSpoolWatcherException;
    await Task.Run(() => spoolWatcher.Run());
}

Как общее примечание, методы Task -обращения должны иметь суффикс Async, поэтому оно должно быть WatchSpoolAsync.

...