异步操作,我做错了......为什么?

时间:2017-07-09 22:07:11

标签: c# asynchronous httpclient

同步代码:

public static void ImportData()
{

    for (var i = 0; i < 40000; i++)
    {
        DoSomething(i)
    }
}

异步代码:

public static void ImportDataAsync()
{
    for (int i = 0; i < 40000; i++)
    {
        await DoSomething(i)
    }
}

为了清楚起见,这是我第一次尝试异步操作。

使用异步代码,我的软件真的很慢,如果我同步运行命令行应用程序的多个实例,它的速度要快10倍。

我的意思是,我不认为DB访问和GetAsync函数的try / catch块会在这两种方法之间做出这种无法区分,你怎么看?

编辑:我不知道如何改进这个问题,但我会尝试给出答案。

我问的是“Parallel.Foreach”方法,我正在做的是认为“await”前缀会将当前线程设置为待机状态并创建另一个线程并继续for循环,而是等待我只是简单地将这种方法留在等待的结果中,然后他在for循环中的同一点回来并在他等待的地方恢复。

我只是混淆了一些东西,特别是在控制台应用程序中,实际上我没有看到任何使用await / async的正当理由。

1 个答案:

答案 0 :(得分:2)

第一次阅读时,也许可能是这个? 20 000对100 000次迭代?

// Sync version
var start = 4000000;
var end = start + 20000;

// Async version
var start = 4000000;
var end = start + 100000

同样在你的异步方法中我看到了一些东西:

  1. public static void ImportAsyncData()public static async Task ImportAsyncData()让来电者等待您的操作

  2. var slot = gs.GetAsync(c);我想你想await来电话:var slot = await gs.GetAsync(c);这样你就不必使用ContinueWith,因为正在等待您的GetAsync调用,因此仅在GetAsync任务完成时才会执行下一行代码。

  3. 你不应该等待忙碌的等待&#34;像这样:while (requestDid - requestDone > 100);,你正在使用你的CPU等待。在这种情况下,您可以在任务之间使用共享变量来考虑并发,可能使用一些简单的lock逻辑。

  4. 你可以将它重构为这样的东西,但我并不了解你想要达到的目标以及你的问题: - )

    public async Task ImportAsyncData()
    {
        var gs = new Site();
    
        int requestDid = 0;
        int requestDone = 0;
        var found = 0;
    
        var watch = System.Diagnostics.Stopwatch.StartNew();
        var start = 4000000;
        var end = start + 100000
    
        var cod = "user"
    
        for (int i = start; i < end; i++)
        {
            var ts = watch.Elapsed;
            string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);
    
            Console.Title = "R: " + (i - start) + " F: " + found + " EL: " + ts;
    
            var c = cod + i;
    
            var user = await gs.GetAsync(c);
            if (user == null)
            {
                requestDone++;
                return;
            }
    
            using (var db = new Database())
            {
                found++;
                db.InsertUser(user);
            }
    
            requestDid++;
        }
    }