/// <summary> /// 文字类型请求 /// </summary> /// <param name="requestMessage"></param> /// <returns></retturns> public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage) { var responseMessage = base.CreateResponseMessage<ResponseMessageText>(); string BotMessage =await MSBot.PostMessage(requestMessage.Content); responseMessage.Content = BotMessage; return responseMessage; }
这个可以有办法转换吗?
public async static Task<string> PostMessage(string message) { HttpClient client; HttpResponseMessage response; bool IsReplyReceived = false; string ReceivedString = null; client = new HttpClient(); client.BaseAddress = new Uri("https://directline.botframework.com/api/conversations/"); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); //client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("BotConnector", "uc0nyMvM0NI.cwA.wYs.B8F1M7cEBm9StsTDG8pmuOjhnxeCJd2LdvNlKVfBgro"); // for leon client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("BotConnector", ""); // for doudou //client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("BotConnector", "iCoMHD3whk8.cwA.50s.vlUvoUn7IjjRuHkSeNZQ2dOIHHTOftz07bAJRF2WJy8"); response = await client.GetAsync("/api/tokens/"); if (response.IsSuccessStatusCode) { var conversation = new Conversation(); StringContent content = new StringContent(JsonConvert.SerializeObject(conversation)); response = await client.PostAsync("/api/conversations/", content); //response = await client.PostAsync("/api/conversations/", null); if (response.IsSuccessStatusCode) { string json = await response.Content.ReadAsStringAsync(); Conversation ConversationInfo = JsonConvert.DeserializeObject<Conversation>(json); //Conversation ConversationInfo = response.Content.ReadAsAsync(typeof(Conversation)).Result as Conversation; string conversationUrl = ConversationInfo.conversationId + "/messages/"; Message msg = new Message() { text = message }; StringContent cont = new StringContent(JsonConvert.SerializeObject(msg)); response = await client.PostAsync(conversationUrl, cont); if (response.IsSuccessStatusCode) { response = await client.GetAsync(conversationUrl); if (response.IsSuccessStatusCode) { string str = await response.Content.ReadAsStringAsync(); MessageSet BotMessage = JsonConvert.DeserializeObject<MessageSet>(str); ReceivedString = BotMessage.messages[1].text; IsReplyReceived = true; } } } } return ReceivedString; }
await Task<string> 的结果就是 string
OnTextRequest这个方法是重写的,它不是异步方法,不能使用await,有没有办法把异步方法封装成同步方法?
@SummerTang: .Result ,但使用 Result 在多线程场景下是有风险的,详见 等到花儿也谢了的await
@SummerTang: 堵塞线程你说怎么写 —— 就那样写,就是同步了。await是封装了这过程而已。
针对httpClient场景,这种你可以直接使用ConfigureAwait(false)方式来后直接拿去result来避免死锁问题,但需要注意的一点是所有await的地方都要这样来一把,外边才能使用.Result,否则是否死锁还要具体看。
另一种方式是强制使用线程池,比如指明LongRunning,Task.Run,这样由于在使用线程池中的线程来跑没有上下文(规避由于一边拿着上下文等着task结束另一边task等着拿到同步上下文才能结束的死锁问题)