PLinq

来源:互联网 发布:淘宝上好看的情侣装店 编辑:程序博客网 时间:2024/06/06 02:48

https://technet.microsoft.com/zh-cn/library/dd460688(v=vs.100)



处理 PLINQ 查询中的异常

本主题中的第一个示例演示如何处理在 PLINQ 查询执行时可能从中引发的 System.AggregateException 第二个示例演示如何将 try-catch 块放在委托内,尽可能靠近将会引发异常的位置。 通过这种方式,一旦发生异常,您就可以捕获它们并且可能继续执行查询。 如果允许异常向上冒泡回到联接线程,则查询操作也许可以在引发异常后继续处理一些项目。

在某些情况下,当 PLINQ 回退到顺序执行并发生异常时,可能会直接传播该异常,而不是包装到 AggregateException 中。 此外,始终可以直接传播ThreadAbortException

注意注意

当启用“仅我的代码”时,Visual Studio 将在引发异常的行上中断运行,并显示错误消息“异常未由用户代码处理”。此错误是良性的。 可以按 F5 从中断处继续运行,并查看在以下示例中演示的异常处理行为。 若要阻止 Visual Studio 在出现第一个错误时中断运行,只需在“工具”->“选项”->“调试”->“常规”下取消选中“仅我的代码”复选框即可。

本示例旨在演示用法,运行速度可能不如等效的顺序 LINQ to Objects 查询快。 有关加速的更多信息,请参见了解 PLINQ 中的加速

示例

此示例演示如何将 try-catch 块放在执行查询以捕获任何引发的 System.AggregateException 的代码的周围。

C#
VB
// Paste into PLINQDataSample class.static void PLINQExceptions_1(){    // Using the raw string array here. See PLINQ Data Sample.    string[] customers = GetCustomersAsStrings().ToArray();    // First, we must simulate some currupt input.    customers[54] = "###";    var parallelQuery = from cust in customers.AsParallel()                        let fields = cust.Split(',')                        where fields[3].StartsWith("C") //throw indexoutofrange                        select new { city = fields[3], thread = Thread.CurrentThread.ManagedThreadId };    try    {        // We use ForAll although it doesn't really improve performance        // since all output is serialized through the Console.        parallelQuery.ForAll(e => Console.WriteLine("City: {0}, Thread:{1}", e.city, e.thread));    }    // In this design, we stop query processing when the exception occurs.    catch (AggregateException e)    {        foreach (var ex in e.InnerExceptions)        {            Console.WriteLine(ex.Message);            if (ex is IndexOutOfRangeException)                Console.WriteLine("The data source is corrupt. Query stopped.");        }    }}

在此示例中,查询在引发异常后无法继续。 到应用程序代码捕获异常时,PLINQ 已经在所有线程上停止了查询。

下面的示例演示如何将 try-catch 块放在委托中,以便能够捕获异常并继续执行查询。

C#
VB
// Paste into PLINQDataSample class.static void PLINQExceptions_2(){    var customers = GetCustomersAsStrings().ToArray();    // Using the raw string array here.    // First, we must simulate some currupt input    customers[54] = "###";    // Create a delegate with a lambda expression.    // Assume that in this app, we expect malformed data    // occasionally and by design we just report it and continue.    Func<string[], string, bool> isTrue = (f, c) =>    {        try        {            string s = f[3];            return s.StartsWith(c);        }        catch (IndexOutOfRangeException e)        {            Console.WriteLine("Malformed cust: {0}", f);            return false;        }    };    // Using the raw string array here    var parallelQuery = from cust in customers.AsParallel()                        let fields = cust.Split(',')                        where isTrue(fields, "C") //use a named delegate with a try-catch                        select new { city = fields[3] };    try    {        // We use ForAll although it doesn't really improve performance        // since all output must be serialized through the Console.        parallelQuery.ForAll(e => Console.WriteLine(e.city));    }    // IndexOutOfRangeException will not bubble up          // because we handle it where it is thrown.    catch (AggregateException e)    {        foreach (var ex in e.InnerExceptions)            Console.WriteLine(ex.Message);    }}

0 0
原创粉丝点击