Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 什么时候是连续的还是并发的?_C#_Async Await - Fatal编程技术网

C# 什么时候是连续的还是并发的?

C# 什么时候是连续的还是并发的?,c#,async-await,C#,Async Await,每次运行以下命令时,都会捕获Mike的异常 什么时候每个任务之间都有连续上下文,还是所有任务都同时运行?如果是同时发生的,为什么迈克的异常总是被发现而不是米奇的。我拖延了迈克的时间,以便给米奇一个机会。如果它是连续的,那么使它并发涉及到什么?在进行web请求/文件处理时是否会应用并发执行 假设这段代码更为严肃,那么这是异步的合理方法吗?场景是几个方法——Jason、Mitch和Mike——在不阻塞的情况下并发运行,并在全部完成后继续事件处理程序?围绕我的异常处理的幼稚实现,我应该注意什么?需要注

每次运行以下命令时,都会捕获Mike的异常

什么时候每个任务之间都有连续上下文,还是所有任务都同时运行?如果是同时发生的,为什么迈克的异常总是被发现而不是米奇的。我拖延了迈克的时间,以便给米奇一个机会。如果它是连续的,那么使它并发涉及到什么?在进行web请求/文件处理时是否会应用并发执行

假设这段代码更为严肃,那么这是异步的合理方法吗?场景是几个方法——Jason、Mitch和Mike——在不阻塞的情况下并发运行,并在全部完成后继续事件处理程序?围绕我的异常处理的幼稚实现,我应该注意什么?需要注意的任何问题或潜在问题

private async void button1_Click(object sender,EventArgs e)
{
    try
    {
        AsyncJason c1 = new AsyncJason();
        await c1.Hello();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

public class AsyncJason
{
    public AsyncJason()
    {
    }

    public async Task Hello()
    {
        var j = await GetJasonAsync();
        string[] dankeSchon = await Task.WhenAll(new Task<string>[] {GetJasonAsync(), GetMikeAsync(), GetMitchAsync()});
    }

    private async Task<string> GetJasonAsync()
    {
        var result = await Task.Run<string>(() => GetJason());
        return result;
    }

    private string GetJason()
    {
        return "Jason";
    }

     private async Task<string> GetMitchAsync()
    {
        var result = await Task.Run<string>(() => GetMitch());
        return result;
    }

    private string GetMitch()
    {
        throw new ArgumentException("Mitch is an idiot", "none");
    }

     private async Task<string> GetMikeAsync()
    {
        await Task.Delay(3000);
        var result = await Task.Run<string>(() => GetMike());
        return result;
    }

    private string GetMike()
    {
        throw new ArgumentException("Mike is an idiot", "none");
    }
}
private async void按钮1\u单击(对象发送方,事件参数e)
{
尝试
{
AsyncJason c1=新的AsyncJason();
等待c1.你好();
}
捕获(例外情况除外)
{
MessageBox.Show(例如Message);
}
}
公共类异步
{
公共服务
{
}
公共异步任务Hello()
{
var j=等待GetJasonAsync();
string[]dankeSchon=wait Task.WhenAll(新任务[]{GetJasonAsync(),GetMikeAsync(),GetMitchAsync()});
}
专用异步任务GetJasonAsync()
{
var result=wait Task.Run(()=>GetJason());
返回结果;
}
私有字符串GetJason()
{
返回“Jason”;
}
专用异步任务GetMitchAsync()
{
var result=wait Task.Run(()=>GetMitch());
返回结果;
}
私有字符串GetMitch()
{
抛出新的ArgumentException(“米奇是个白痴”,“没有”);
}
专用异步任务GetMikeAsync()
{
等待任务。延迟(3000);
var result=wait Task.Run(()=>GetMike());
返回结果;
}
私有字符串GetMike()
{
抛出新的ArgumentException(“迈克是个白痴”,“没有”);
}
}
什么时候是连续的还是并发的

这个问题实际上并不适用。当所有基础任务完成时,
whalll
的任务完成。如何做到这一点是它的事

在异常方面,
任务
异常
属性包含一个
聚合异常
,该异常包含所有基础任务引发的所有异常

当您等待一个包含表示多个异常的聚合异常的任务时,它将打开并重新抛出该列表中的第一个异常,而不是包含所有异常的
aggregateeexception

创建
aggregateeexception
时,它(显然;我不知道这是否在任何地方得到保证)会根据所有
时传递给
的任务的顺序列出异常,而不是根据这些任务完成的顺序

如果您担心丢失的异常,那么您应该存储它返回的任务,以便您可以检查所有异常,或者只是重新播放包装的
聚合异常
,即:

public async Task Hello()
{
    var j = await GetJasonAsync();
    var task = Task.WhenAll(new Task<string>[] { GetJasonAsync(), GetMikeAsync(), GetMitchAsync() });
    try
    {
        string[] dankeSchon = await task;
    }
    catch (Exception)
    {
        throw task.Exception;
    }
}
基本上,这里的想法是为每个任务创建一个
TaskCompletionSource
,为提供给我们的每个任务添加一个延续,然后当任何任务完成时,我们将尚未完成的TaskCompletionSource标记为刚完成任务的结果

利用这个,我们现在可以写:

public async Task Hello()
{
    var j = await GetJasonAsync();
    var tasks = new[] { GetJasonAsync(), GetMikeAsync(), GetMitchAsync() };
    string[] dankeSchon = await Task.WhenAll(tasks.Order());
}

并且异常将是第一个抛出的异常。

当无法控制任务的执行方式时(即所有任务都可以在
当所有
执行时完成)…将不会
抛出任务。异常吹走异常的堆栈跟踪?@ScottChamberlain的聚合异常,是的。在内部异常中,我不希望如此。我记得看到过一个C#5.0工具的示例,可以使用它在不清除堆栈的情况下重新引发异常,但我没有花时间再次查找它;理论上可以在这里应用。
public async Task Hello()
{
    var j = await GetJasonAsync();
    var tasks = new[] { GetJasonAsync(), GetMikeAsync(), GetMitchAsync() };
    string[] dankeSchon = await Task.WhenAll(tasks.Order());
}