【发布时间】:2014-08-06 23:51:13
【问题描述】:
我们正在使用来自 MVC 站点的 WebAPI。我们从这样的控制台应用程序进行了概念验证,使用 AddUser 方法,该方法在我们的数据库中注册一个新用户。
static void Main()
{
M_Users user = new M_Users();
var newUser = new M_Users()
{
Password = "123",
FirstName = "Andrew",
Email = "someAndrew@someplace.com",
AdminCode = 1,
IsDisabled = false,
CountryId = 48,
CityId = 149,
DepartmentId = 3,
CreationDate = DateTime.Now,
CreatorUserId = 1
};
var star = RunAsync(newUser);
star.Wait();
//THIS LINE IS REACHED ALWAYS
Console.WriteLine(star.Result.UserID);
Console.ReadLine();
}
static async Task<M_Users> AddUserAsync(M_Users newUser)
{
M_Users user = new M_Users();
string requestUri = "api/User/AddUser";
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:44873/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// HTTP POST
HttpResponseMessage response = await client.PostAsJsonAsync<M_Users>(requestUri, newUser);
if (response.IsSuccessStatusCode)
{
Uri newUserUrl = response.Headers.Location;
user = await response.Content.ReadAsAsync<M_Users>();
}
return user;
}
}
这个 AddUserAsync 方法在两种情况下调用完全相同,控制台应用程序和 MVC 应用程序,以及 biz 层中的方法也是相同的,这里没有描述似乎不相关。
在控制台中它刚刚工作。用户已注册,控制台打印了用户在 BD 中保存的 ID。这几乎就是我们需要证明的。我们可以从同步方法调用异步方法。现在我们从我们网站的控制器中尝试相同的操作,就像这样。
public ActionResult Index()
{
User spUser = null;
var spContext = SharePointContextProvider.Current.GetSharePointContext(HttpContext);
var model = new LoginViewModel();
// here we invoke sharepoint context for getting user info to bild the object
M_Users new_user = new M_Users()
{
Password = "123",
FirstName = spUser.Title,
Email = spUser.LoginName.Split('|')[2].ToString(),
AdminCode = 1,
IsDisabled = false,
CountryId = 48,
CityId = 149,
DepartmentId = 3,
CreationDate = DateTime.Now,
CreatorUserId = 1
};
var returnedUser = AddUserAsync(new_user);
returnedUser.Wait(); //HERE IT STOPS RUNNING
//THIS LINE IS NEVER REACHED
ViewBag.UserId = returnedUser.Result.UserID;
return View(model);
}
需要做什么才能继续执行。
我们也尝试了 ContinueWith() 并且它运行了,但是 async 方法没有被执行并且数据库中没有任何记录。更具体地说,该方法被调用,但它似乎越过了它并且没有返回任何内容。 :(
【问题讨论】:
-
这是使用异步的常见问题之一。请参阅 Stephen Cleary 的帖子blog.stephencleary.com/2012/07/dont-block-on-async-code.html。解决死锁的一种方法是像
public async Task<ActionResult> Index这样更改操作方法。然后,使用var result = await returnedUser;,而不是returnedUser.Wait();。
标签: c# asp.net-web-api asp.net-mvc-5 async-await