C#在线程内部调用异步方法

时间:2019-02-26 12:33:12

标签: c# multithreading asynchronous

也许我没有在论坛中正确搜索,因为我没有发现类似的问题。
好吧,我的问题是当我尝试在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 :(得分:4)

您的问题是由于使用了should be avoidedasync void。其问题之一是您无法使用try / catch捕获异常。

C#中的事件处理程序是一种“一劳永逸”的语言功能。特别是,异步事件处理程序必须使用async void,这意味着事件发布代码无法看到那些异常。如果要允许async事件处理程序并处理其中的异常(或其他结果),则可以使用"deferral" solution或使事件处理程序委托返回Task

答案 1 :(得分:1)

异步void将不允许您捕获任何异常,并且在引发异常时将终止您的应用程序。仅在使用task而不是void时才观察到异常并将其作为普通异常处理。

您可以在link

上阅读全部内容

我无法回答您的第一个问题,即如果没有更多信息,没有线程为什么它可以工作。我可以保证,就我所知,它与多线程无关,因为主线程也只是任何其他线程。