添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I'm using the Poloniex C# API code from: https://github.com/Jojatekok/PoloniexApi.Net

On my console application the request to get balances is working, i make the API call and the balances come back, but on my Windows Forms application it's not getting past waiting for the balances:

Id = 14, Status = WaitingForActivation, Method = "{null}", Result = "{Not yet computed}"

when using this code:

PoloniexClient polo_client { get; set; }
private void Main(){
    polo_client = new PoloniexClient(ApiKeys.PublicKey, ApiKeys.PrivateKey);
    var balance_task = getLatestWalletAmounts();
    balance_task.Wait();
    // doesn't get past here on my Forms app
    if (balance_task.IsCompleted){
          // gets to here on my Console app
// get wallet and startup amounts
async Task<IDictionary<string, Jojatekok.PoloniexAPI.WalletTools.IBalance>> getLatestWalletAmounts()
   // get wallet coin list 
   return await polo_client.Wallet.GetBalancesAsync();  

It's the exact same code as my Console application, but on the Forms app the task is not completing and on the Console application it is completing and i'm getting back:

Id = 3, Status = RanToCompletion, Method = "{null}", Result = "System.Collections.Generic.Dictionary`2[System.String,Jojatekok.PoloniexAPI.WalletTools.IBalance]"

Any hints as to why the same request isn't completing on my Forms application but it is on my Console app? I'm using the exact same Poloniex C# project referenced in my Console and Forms app to interact with the API.

The API public key is the same in both projects and the API private key is the same in both projects.

You cannot mix async and synchronous code like this. By calling .Wait, the UI thread is stuck waiting for the task to finish, but the task is essentially trying to "Invoke" on the UI thread, so it cannot finish. Result: deadlock.

You can see more information about the basic problem here.

One option, as a band-aid, is to use ConfigureAwait(false) on the await polo_client.Wallet.GetBalancesAsync() call; that will override the default behavior of trying to return to the UI thread. (Note that means you can't access the UI after the await, because it will be continuing on a different thread!)

I have written a longer piece here about bringing async code into the core of a UI application.

Ahhh so this is why it works on my Console application? Because it doesn't have UI.. that makes sense. – Nickmccomb May 10, 2016 at 22:42

This looks like a classic async-await deadlock: you have a SynchronizationContext, you await in it (which means the continuation is scheduled to that SynchronizationContext) and then you block that SynchronizationContext by calling Wait(), which leads to deadlock.

The right solution to not block on async code, your Main should be an async method that returns a Task and awaits balance_task. Another option is to use ConfigureAwait(false) in getLatestWalletAmounts() (and any other "library" method that uses await).

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.