【问题标题】:Deadlock when using await GetResponseAsync()使用 await GetResponseAsync() 时出现死锁
【发布时间】:2015-12-25 20:45:02
【问题描述】:

我已经使用 Visual Studio 2015 中的控制台应用程序成功地将 json 数据提取到一个字符串中。现在我尝试为 wpf 复制它,但我发现我不能使用 .GetResponse() 并且我有改为使用 GetResponseAsync()。谷歌搜索了一段时间后,我想我理解了异步/等待的意义,但我似乎陷入了僵局。所以这是我当前的代码:

这是从 Web API 提取返回数据并返回 JSON 字符串的异步方法。或者在这种情况下为Task<String>

public async static Task<String> GetTrola(string station)
        {
            var url = "http://www.trola.si/" + station;

            string text;

            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            request.Accept = "application/json";

            var answer = (HttpWebResponse)(await request.GetResponseAsync());

            using (var sr = new StreamReader(answer.GetResponseStream()))
            {
                text = sr.ReadToEnd();
            }
            return text;
        }

然后我在按钮单击事件中调用该函数,如下所示:

string station = textBox.Text.ToString();
string output = GetJson.Trola.GetTrola(station).Result;
var myObject = JsonConvert.DeserializeObject<Result>(output);

但我认为问题出在 GetData 函数中,尤其是这一行:

var answer = (HttpWebResponse)(await request.GetResponseAsync());

我不知道为什么会这样,因为我在等待带有 await 关键字的请求?我还缺少什么?

【问题讨论】:

    标签: c# json wpf asynchronous


    【解决方案1】:

    在这一行

    string output = GetJson.Trola.GetTrola(station).Result;
    

    您正在阻塞 UI 线程。 GetDataawait 之后的部分需要在同一线程上运行。死锁。

    您应该使用await 来获取结果

    string output = await GetJson.Trola.GetTrola(station);
    

    你可以在Stephen Cleary's blog找到非常详细的解释。

    【讨论】:

    • 嗯,我正在尝试,但我想我误读/误解了错误。由于我在无效的 button_click 方法中调用方法 .getTrola,因此我不能在其中使用 await 运算符。所以我应该写一个新的async方法,在button_clicked方法中调用吧?
    • @mythic 创建事件处理程序async void。然后你可以在里面使用await。通常async 方法应该返回Task,但在事件处理程序中使用async void 是可以接受的。
    【解决方案2】:

    例如,我可以参考this 代码和存储库,这正是您想要的。

    public async Task<TranslateResult> Find(TranslateRequest translateRequest)
    {
        if (!configuration.IsAppropriateForTranslation(TranslatorType))
            return new TranslateResult(false, new Maybe<string>());
    
        var address = configuration.TurengUrl;
        var uri = new Uri(address + translateRequest.CurrentText);
    
        var turenClient = new WebClient();
        turenClient.Encoding = Encoding.UTF8;
        turenClient.Headers.Add(HttpRequestHeader.UserAgent, "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.81 Safari/537.36");
        turenClient.Headers.Add(HttpRequestHeader.AcceptLanguage, "en-US,en;q=0.8,tr;q=0.6");
        turenClient.CachePolicy = new HttpRequestCachePolicy(HttpCacheAgeControl.MaxAge, TimeSpan.FromHours(1));
    
        var compositeMean = await turenClient.DownloadStringTaskAsync(uri);
        var organizer = meanOrganizerFactory.GetMeanOrganizers().First(x => x.TranslatorType == TranslatorType.TURENG);
        var mean = await organizer.OrganizeMean(compositeMean);
    
        return new TranslateResult(true, mean);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多