【问题标题】:What am I doing wrong with async/await? [closed]我做错了什么异步/等待? [关闭]
【发布时间】:2014-07-29 10:08:20
【问题描述】:

我正在创建一个基本上为我玩游戏的应用程序。它形成突袭,加入突袭,然后发起突袭。我正在尝试异步执行所有操作。

一些背景知识:FormRaidAsync、JoinRaidAsync 和 LaunchRaidAsync 都发出 Web 请求。方法本身也设置为异步的,但是当我运行程序时,它每秒只加入大约 2-3 个帐户。

是我做错了什么,还是 async/await 不一定在新线程上运行每个请求?如果是这种情况,我如何调整此代码以接近 10/秒的速度加入帐户?我是否必须使用其他形式的多线程来一次发出更多请求?

谢谢大家。如果需要更多详细信息,请告诉我。

public async Task<string> StartRaidAsync()
{
    string raid_id = String.Empty;

    try
    {
        raid_id = await this.Helper.FormRaidAsync(this.TargetRaid.Id, this.Former.Id, this.TargetRaid.IsBossRaid).ConfigureAwait(false);
        Console.WriteLine("Formed raid with {0}.", this.Former.Name);

        List<Task> joinTasks = new List<Task>();

        foreach (var joiner in this.Joiners)
        {
            try
            {
                joinTasks.Add(this.Helper.JoinRaidAsync(raid_id, joiner.Id));
            }
            catch (Exception)   // Not sure which exceptions to catch yet.
            {
                Console.WriteLine("Error joining {0}. Skipped.", joiner.Name);
            }
        }

        Task.WaitAll(joinTasks.ToArray());

        await this.Helper.LaunchRaidAsync(raid_id, this.Former.Id).ConfigureAwait(false);
        Console.WriteLine("{0} launched raid.", this.Former.Name);
    }
    catch (Exception)   // Not sure which exceptions to catch yet.
    {
        return "ERROR";
    }

    return raid_id;
}

在 JoinRaidAsync 内部:

public async Task JoinRaidAsync(string raid_id, string suid)
{
    var postUrl = "some url";
    var postData = "some data";

    await this.Socket.PostAsync(postUrl, postData).ConfigureAwait(false);
    Console.WriteLine("Joined {0}.", suid);
}

Socket.PostAsync 内部:

public async Task<string> PostAsync(string url, string postData)
{
    return await SendRequestAsync(url, postData).ConfigureAwait(false);
}

在 SendRequestAsync 内部:

protected virtual async Task<string> SendRequestAsync(string url, string postData)
{
    for (int i = 0; i < 3; i++)
    {
        try
        {
            HttpWebRequest request = this.CreateRequest(url);

            if (!String.IsNullOrWhiteSpace(postData))
            {
                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded";
                request.ContentLength = postData.Length;
                var stream = await request.GetRequestStreamAsync().ConfigureAwait(false);

                using (StreamWriter writer = new StreamWriter(stream))
                {
                    await writer.WriteAsync(postData).ConfigureAwait(false);
                    await writer.FlushAsync().ConfigureAwait(false);
                }
            }

            using (HttpWebResponse response = (HttpWebResponse)(await request.GetResponseAsync().ConfigureAwait(false)))
            {
                string responseString = String.Empty;

                using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                {
                    responseString = await reader.ReadToEndAsync().ConfigureAwait(false);
                }

                return responseString;
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }

    return String.Empty;
}

【问题讨论】:

  • 当您“不确定要捕获哪些异常”时不要捕获异常。让它冒泡。如果您最终找到一个不想冒泡的异常,您现在就可以准确地知道要捕获哪个异常。
  • 这是有道理的。感谢您指出这一点。
  • 能否请您更具体地说明您遇到了什么问题。

标签: c# multithreading async-await


【解决方案1】:

是我做错了什么,还是 async/await 不一定在新线程上运行每个请求?

async/await 不会创建新线程。

如果是这种情况,我如何调整此代码以接近 10/秒的速度加入帐户?

异步代码可以一次执行多个请求。当然,这些请求的速度取决于 Web 服务调用的速度。

我现在在代码中看到的唯一错误是它混合了阻塞和异步代码。替换:

Task.WaitAll(joinTasks.ToArray());

与:

await Task.WhenAll(joinTasks.ToArray());

如果您仍然看到问题,可能是由于您的 Web 服务或其他支持代码(例如 JoinRaidAsync 中的代码)。

【讨论】:

  • 感谢斯蒂芬回复。我已经阅读了很多关于异步和等待的博客文章。我只是将我的脚趾浸入其中,并试图了解它是如何运作的。我已经更新了我的主要问题,以将流程包括到实际的 Web 请求。如果您立即发现任何错误,请告诉我。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-19
  • 1970-01-01
  • 2012-11-07
  • 2013-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多