使用Microsoft for .NET的异步CTP,是否可以捕获调用方法中异步方法抛出的异常?
public async void Foo()
{
var x = await DoSomethingAsync();
/* Handle the result, but sometimes an exception might be thrown.
For example, DoSomethingAsync gets data from the network
and the data is invalid... a ProtocolException might be thrown. */
}
public void DoFoo()
{
try
{
Foo();
}
catch (ProtocolException ex)
{
/* The exception will never be caught.
Instead when in debug mode, VS2010 will warn and continue.
The deployed the app will simply crash. …Run Code Online (Sandbox Code Playgroud) c# asynchronous exception-handling task-parallel-library async-await
我正在尝试基于VS2013项目模板中的示例AccountController为ASP.NET MVC5网站设置电子邮件确认.我已经实现了IIdentityMessageService使用SmtpClient,试图尽可能简单:
public class EmailService : IIdentityMessageService
{
public async Task SendAsync(IdentityMessage message)
{
using(var client = new SmtpClient())
{
var mailMessage = new MailMessage("some.guy@company.com", message.Destination, message.Subject, message.Body);
await client.SendMailAsync(mailMessage);
}
}
}
Run Code Online (Sandbox Code Playgroud)
调用它的控制器代码直接来自模板(由于我想排除其他可能的原因,因此将其解压缩为单独的操作):
public async Task<ActionResult> TestAsyncEmail()
{
Guid userId = User.Identity.GetUserId();
string code = await UserManager.GenerateEmailConfirmationTokenAsync(userId);
var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = userId, code = code }, protocol: Request.Url.Scheme);
await UserManager.SendEmailAsync(userId, "Confirm your account", "Please confirm your account by clicking <a …Run Code Online (Sandbox Code Playgroud) 我需要一些帮助来找出问题所在.我已经使用了ASP.NET核心,我对此非常熟悉,尽管.NET核心C#似乎在"崩溃"并且在尝试发出异步请求时退出.
我有一个返回系统外部IP的方法
private async Task<string> getExternalIP()
{
using (System.Net.Http.HttpClient HC = new System.Net.Http.HttpClient())
{
return await HC.GetStringAsync("https://api.ipify.org/");
}
}
Run Code Online (Sandbox Code Playgroud)
这应该可以工作,但是当它到达HC.GetStringAsync时会退出.我也试过在它上面设一个断点,但它实际上并没有运行.
我试图通过使用调用该方法
string Address = await getExternalIP();
Run Code Online (Sandbox Code Playgroud)
任何帮助都很感激,希望我不只是忽略了一些东西.
谢谢!
摘自Stephen Cleary关于异步等待的文章:
图2异步无效方法的异常无法通过Catch捕获
private async void ThrowExceptionAsync()
{
throw new InvalidOperationException();
}
public void AsyncVoidExceptions_CannotBeCaughtByCatch()
{
try
{
ThrowExceptionAsync();
}
catch (Exception)
{
// The exception is never caught here!
throw;
}
}
Run Code Online (Sandbox Code Playgroud)
...异步void方法抛出的任何异常将直接在异步void方法启动时处于活动状态的SynchronizationContext上引发...
这究竟意味着什么?我写了一个扩展示例来尝试收集更多信息.它具有与图2相同的行为:
static void Main()
{
AppDomain.CurrentDomain.UnhandledException += (sender, ex) =>
{
LogCurrentSynchronizationContext("AppDomain.CurrentDomain.UnhandledException");
LogException("AppDomain.CurrentDomain.UnhandledException", ex.ExceptionObject as Exception);
};
try
{
try
{
void ThrowExceptionVoid() => throw new Exception("ThrowExceptionVoid");
ThrowExceptionVoid();
}
catch (Exception ex)
{
LogException("AsyncMain - Catch - ThrowExceptionVoid", ex);
}
try
{
// CS1998 …Run Code Online (Sandbox Code Playgroud) 我有以下场景:
当输入命令时(为了测试,它是一个控制台应用程序,当它准备就绪时,我希望它将是一个WebService)我执行一些代码,当需要进一步的用户输入时,我返回命令立即翻译.当给出新输入时,我希望处理从我离开它的地方继续.这听起来很像c#5 async-await模式,我决定尝试一下.我在想这个:
public void CommandParser()
{
while(true)
{
string s = Console.ReadLine();
if (s == "do_something")
Execute();
else if (s == "give_parameters")
SetParameters();
//...
}
}
MySettings input;
public async void Execute()
{
//do stuff here
MyResult result = null
if (/*input needed*/){
input = new MySetting();
result = await input.Calculate();
}
else { /* fill result synchronously*/}
//do something with result here
}
public void SetParameters()
{
if (input!=null)
input.UseThis("something"); //now it can return from await
}
Run Code Online (Sandbox Code Playgroud)
现在我的问题是,如何编写MySettings.Calculate和MySettings.UseThis?如何从第一个返回任务以及如何从第二个发出准备信号?我已尝试过许多工厂方法的Task,但我找不到合适的方法!请帮忙!
c# ×5
async-await ×4
.net ×2
asynchronous ×2
.net-core ×1
asp.net-mvc ×1
c#-5.0 ×1
smtpclient ×1