为什么这个异步/等待代码死锁?

时间:2015-09-24 16:05:40

标签: c# asynchronous async-await deadlock ui-thread

我有以下代码,当调用它的预期方式时,它会在我尝试直接访问任务的Result属性时锁定。

我没想到这一点,特别是当我指定ConfigureAwait(false)时。另外,我不确定是否应该保留由实现IDisposable的cancellationToken.Register方法返回的实例的引用(以及dispose where?)。

public async void SomeUIThreadHandlerMethod()
{
    // works
    var contactsWorks = await instance.ScanContactsAsync(CancellationToken.None);
    // Locks
    var contactsLocks = instance.ScanContactsAsync(CancellationToken.None).Result;
    // Locks
    var contactsLocks = instance.ScanContactsAsync(CancellationToken.None).GetAwaiter().GetResult();
}


public async Task<ICollection<Contact>> ScanContactsAsync(CancellationToken cancellationToken)
{
    var contactsCompletion = new TaskCompletionSource<ICollection<Contact>>();

    try
    {
        cancellationToken.Register(state => ((TaskCompletionSource<ICollection<Contact>>)state).TrySetCanceled(), contactsCompletion);

        var contacts = new Contacts();

        contacts.SearchCompleted += (_, args) => contactsCompletion.TrySetResult(args.Results.ToArray());

        contacts.SearchAsync(string.Empty, FilterKind.None, null);
    }
    catch (Exception ex)
    {
        contactsCompletion.TrySetException(ex);
    }

    return await contactsCompletion.Task.ConfigureAwait(false);
}

0 个答案:

没有答案