1

The following code is working fine: its sample code downloaded from GitHub and set with my image and API keys.

 static void Main(string[] args)
    {
        Foo().GetAwaiter().GetResult();
        Console.ReadKey();
    }

    static async Task Foo()
    {
        var antiCaptcha = new AntiCaptcha("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");

        // Get current balance
        var balance = await antiCaptcha.GetBalance();

        string base64captcha = "Here is a base64 string of a captcha";

        // Solve image captcha
        var image = antiCaptcha.SolveImage(base64captcha);
        image.Wait();

        var res = image.Result;
}

My application is different: There I have also implemented the same.

 public async Task<AntiCaptchaResult> AntiCaptchaSolution(string ApplicationId, string captchaBase64, string Success)
    {
        var antiCaptcha = new AntiCaptcha("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");

        // Solve image captcha
        var image = antiCaptcha.SolveImage(captchaBase64);
        image.Wait();

        return image.Result;
    }

When I don't debug it does not respond anything.

And When I am debugging, the debugger disappears after the anticaptcha.SolveImage line and never comes and nothing happens afterward.

**I am calling this method from another method: **

 public string GetFirstCaptcha(string Success="False")
    {
captchasrc = "";
var res = AntiCaptchaSolution(applicationid, captchasrc, Success).GetAwaiter().GetResult();
    }
ilkerkaran
  • 4,214
  • 3
  • 27
  • 42
Abdur Rahim
  • 3,975
  • 14
  • 44
  • 83
  • 1
    Maybe you can provide the full source code of your project or at least the calling part as well. – Alexander May 09 '19 at 11:12
  • 3
    The `image.Wait();` will block the current thread. Same as the other `image.Wait();`. I don't see any `Task.Run()`/`await`. The current code is all running on the current thread. In this case the Tasks are useless. You should read the [`Task.Run()`](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.run?view=netframework-4.8#System_Threading_Tasks_Task_Run_System_Func_System_Threading_Tasks_Task__) documentation. – Jeroen van Langen May 09 '19 at 11:14
  • As far as I know it's quite dangerous to do Wait() in an async method if you don't know what you are doing, try using await intead – Ilya Chernomordik May 09 '19 at 11:17
  • @J.vanLangen My first provided code sample is running fine. which is downloaded from a git repo. I don't see the difference. can you please help? – Abdur Rahim May 09 '19 at 11:17
  • Just to add to the above, this would be much simpler if you used a `async` Main and awaited the `Task`s – deadwards May 09 '19 at 11:18
  • The difference can be in where you run it, async contexts will differ – Ilya Chernomordik May 09 '19 at 11:18
  • Your first sample is for a console application. Is your actual application also console? – GSerg May 09 '19 at 11:19
  • The first example probably gives a warning that no await is used within the async method. – Jeroen van Langen May 09 '19 at 11:20
  • No, desktop, WPF @GSerg – Abdur Rahim May 09 '19 at 11:21
  • 4
    Then you should really read https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html. – GSerg May 09 '19 at 11:22
  • Okay, I am calling this method in 8-9th step inside of the main method. that means between the start point to this method there are 8 different methods. Do I have to make all of them asysnc? @GSerg – Abdur Rahim May 09 '19 at 12:03
  • @AbdurRahim Yes, that is how it works. Async grows through everything and consumes you whole. – GSerg May 09 '19 at 12:05
  • @GSerg But thats a huge change in my project. this captcha part is very simple part in that. Can you suggest any other way please? – Abdur Rahim May 09 '19 at 12:08
  • Okay, I think I can seperate this part to another class fully and take just the result from that? – Abdur Rahim May 09 '19 at 12:09
  • 2
    It will deadlock on the `.Result` anyway. If you want to use async, use async all the way. If you don't want async, use e.g. background workers. If you have an async method that you want to run from non-async anyway, see https://stackoverflow.com/q/9343594/11683. – GSerg May 09 '19 at 12:19
  • @GSerg I created a new class library and moved these async code to that and just called the async method from where I needed and its working fine now :D do you think its a good solution? – Abdur Rahim May 09 '19 at 13:17

1 Answers1

3

I suggest that you use await everywhere you are doing .Wait() now. It is non trivial to understand the complexity of async/await and how it does work, but one thing is clear: better not to combine async with blocking .Wait(). It can result in a deadlock.

There are many explanations around the web, e.g. here.

Alternatively if you don't have async/await in your whole stack, you can just remove async from your AntiCaptchaSolution method, and do an ordinary blocking call with .Result/.Wait(), but then it will of course not be asynchronous.

Ilya Chernomordik
  • 27,817
  • 27
  • 121
  • 207
  • I was using await then, but that was same result. so I was trying using `Wait()` – Abdur Rahim May 09 '19 at 11:20
  • You have to use async/await all the way up the whole stack, not only in the method itself – Ilya Chernomordik May 09 '19 at 11:21
  • okay, wait a bit. I am doing the same as you saying and let you know – Abdur Rahim May 09 '19 at 11:22
  • Okay, I am calling this method in 8-9th step inside of the main method. that means between the start point to this method there are 8 different methods. Do I have to make all of them asysnc? – Abdur Rahim May 09 '19 at 12:03
  • Yes, unfortunately it works this way. If you begin with async on the very top, the whole stack should become async. Alternatively you can make AntiCaptchaSolution to an ordinary method instead of async, then you can do a blocking call as before, but if you don't have async the whole way, it won't really be "real" async – Ilya Chernomordik May 09 '19 at 12:48
  • I created a new class library and moved these async code to that and just called the async method from where I needed and its working fine now :D do you think its a good solution? – Abdur Rahim May 09 '19 at 13:16
  • Hard to say really without knowing all of the details, but if it is working and using async all the way I assume so :) – Ilya Chernomordik May 09 '19 at 13:20