C # Вызов асинхронного метода внутри потока - PullRequest
0 голосов
/ 26 февраля 2019

Возможно, я не выполнил правильный поиск здесь на форуме, потому что не нашел подобной проблемыЧто ж, моя проблема в том, что когда я пытаюсь выполнить метод async внутри thread.

Когда я запускаю метод (Register) без thread, он работает отлично!Ниже приведен пример сценария.

private SyncProcess _sync = new SyncProcess();
private static HttpClient _httpClient = new HttpClient();
private Thread _thread;

public class SyncProcess : ISyncProcess
{
    public event CompleteHandler OnComplete = delegate { };
    // another properties ...

    public void Run()
    {
        // import rules
        // ...
        OnComplete();
    }
}

public void TestImport()
{
    Register(idsync, "start"); // here register works fine
    _sync.OnComplete += ImportComplete;
    _thread = new Thread(() =>
    {
        try
        {
            _sync.Run();
        }
        catch (Exception ex)
        {
            // not fall here
        }
    });
    //
    _thread.Start();
}

private void ImportComplete()
{
    // other end-of-import rules
    // ...
    Register(idsync, "complete");  // here register not works
}

public async Task<string> Register(int idsync, string type)
{
    string url = "myurl";
    var stringContent = new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("json", "myjson") }); 
    var response = await _httpClient.PostAsync(url + type, stringContent);
    if (response.IsSuccessStatusCode)
    {
        // do something
    }
    return "";
}

Проблема возникает, когда я вызываю метод (Register) внутри потока, другая вещь заключается в том, что он не генерирует ошибку,не попадая в try, отладка просто прекращается.Я пытался добавить код try везде, но никогда не вылетал в catch.Отладка всегда прерывается в следующей строке:

var response = await _httpClient.PostAsync(url + type, stringContent);

Что мне делать в этом случае?

Обновлен код, возвращающий строку в методе Register, но остается та же ошибка.Спасибо за любые предложения!

Ответы [ 2 ]

0 голосов
/ 26 февраля 2019

Ваша проблема связана с использованием async void, которого следует избегать .Одна из его проблем заключается в том, что вы не можете перехватывать исключения, используя try / catch.

Обработчики событий в C # - это языковая функция типа «запусти и забудь».В частности, асинхронные обработчики событий должны использовать async void, и это означает, что код публикации событий не может видеть эти исключения.Если вы хотите разрешить async обработчики событий и обрабатывать исключения (или другие результаты) из них, вы можете использовать «отложенное» решение или сделать так, чтобы ваш делегат обработчика событий возвращал Task.

0 голосов
/ 26 февраля 2019

Async void не позволит вам перехватить какие-либо исключения и прекратит работу вашего приложения, когда оно будет брошено.Исключения наблюдаются и обрабатываются как обычные исключения при использовании задачи вместо void.

Вы можете прочитать все об этом здесь ссылка

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

...