Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/93.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#_.net_Exception Handling - Fatal编程技术网

C# 如何通知异常并继续

C# 如何通知异常并继续,c#,.net,exception-handling,C#,.net,Exception Handling,我正在编写一个库(作为Nuget包分发),它允许用户将多个“读取器”配置到存储库。它遍历每个读卡器,并通过第一个可用的读卡器访问存储库 读卡器处于可用状态,不可用也不例外。但是,还有一些其他的异常情况需要通知调用应用程序。通知后,程序应该能够尝试使用下一个读卡器 这些是我考虑过的选择 抛出异常:这里的问题是控制流返回 累积状态和返回:读者有其他东西要返回,我 不希望将状态与它捆绑在一起 抛出异常:看起来很可怕:)就像它可能会创建 孤立线程或内存泄漏 事件处理:我不确定如何通过事件处理 下面是一

我正在编写一个库(作为Nuget包分发),它允许用户将多个“读取器”配置到存储库。它遍历每个读卡器,并通过第一个可用的读卡器访问存储库

读卡器处于可用状态,不可用也不例外。但是,还有一些其他的异常情况需要通知调用应用程序。通知后,程序应该能够尝试使用下一个读卡器

这些是我考虑过的选择

  • 抛出异常:这里的问题是控制流返回
  • 累积状态和返回:读者有其他东西要返回,我 不希望将状态与它捆绑在一起
  • 抛出异常:看起来很可怕:)就像它可能会创建 孤立线程或内存泄漏
  • 事件处理:我不确定如何通过事件处理

下面是一个协调器示例,它将返回结果和处理过程中发生的任何异常

public class Coordinator<T> where T: new()
{
    public async Task<Tuple<IEnumerable<T>, AggregateException>> GetResultsAsync()
    {
        var tasks = new Task<T>[10];
        for(int i = 0; i < 10; i++)
        {
            tasks[i] = Task.Run(() => GetResult(i));
        }

        var results = new List<T>();
        var exceptions = new List<Exception>();

        foreach(var item in tasks)
        {
            try
            {
                var result = await item;
                results.Add(result);
            }
            catch(Exception e)
            {
                exceptions.Add(e);
            }
        }

        return Tuple.Create<IEnumerable<T>, AggregateException>(results, new AggregateException(exceptions));
    }

    private T GetResult(int i)
    {
        if (i % 2 == 0) throw new Exception("Result cannot be even.");
        return new T();
    }
}
公共类协调器,其中T:new()
{
公共异步任务GetResultsAsync()
{
var任务=新任务[10];
对于(int i=0;i<10;i++)
{
tasks[i]=Task.Run(()=>GetResult(i));
}
var results=新列表();
var exceptions=新列表();
foreach(任务中的变量项)
{
尝试
{
var结果=等待项;
结果。添加(结果);
}
捕获(例外e)
{
例外情况。添加(e);
}
}
返回Tuple.Create(results,newaggregateeexception(exceptions));
}
私有T GetResult(int i)
{
如果(i%2==0)抛出新异常(“结果不能是偶数”);
返回新的T();
}
}

下面是一个协调器示例,它将返回结果和处理过程中发生的任何异常

public class Coordinator<T> where T: new()
{
    public async Task<Tuple<IEnumerable<T>, AggregateException>> GetResultsAsync()
    {
        var tasks = new Task<T>[10];
        for(int i = 0; i < 10; i++)
        {
            tasks[i] = Task.Run(() => GetResult(i));
        }

        var results = new List<T>();
        var exceptions = new List<Exception>();

        foreach(var item in tasks)
        {
            try
            {
                var result = await item;
                results.Add(result);
            }
            catch(Exception e)
            {
                exceptions.Add(e);
            }
        }

        return Tuple.Create<IEnumerable<T>, AggregateException>(results, new AggregateException(exceptions));
    }

    private T GetResult(int i)
    {
        if (i % 2 == 0) throw new Exception("Result cannot be even.");
        return new T();
    }
}
公共类协调器,其中T:new()
{
公共异步任务GetResultsAsync()
{
var任务=新任务[10];
对于(int i=0;i<10;i++)
{
tasks[i]=Task.Run(()=>GetResult(i));
}
var results=新列表();
var exceptions=新列表();
foreach(任务中的变量项)
{
尝试
{
var结果=等待项;
结果。添加(结果);
}
捕获(例外e)
{
例外情况。添加(e);
}
}
返回Tuple.Create(results,newaggregateeexception(exceptions));
}
私有T GetResult(int i)
{
如果(i%2==0)抛出新异常(“结果不能是偶数”);
返回新的T();
}
}

当应用程序继续运行时,在调用方看来,这些都不是例外。异常应始终中止

我会做一些类似.NET内部所做的事情,并有一个事件

public class ReaderFailedEventArgs : EventArgs
{
    public ReaderFailedEventArgs (IReader reader, Exception failure)
    {
    }

    // [.. Two read only properties here ..]
}

public class Worker
{
    public event EventHandler<ReaderFailedEventArgs> ReaderFailed = delegate{};

    public IEnumerable<Data> Process()
    {
        foreach (var reader in _readers)
        {
            try
            {
                return reader.Read();
            }
            catch (Exception ex)
            {
                ReaderFailed(this, new ReaderFailedEventArgs(reader, ex);
            }
        }

        // now, this is a real exception since user expects to get data
        throw new InvalidOperationException("All readers failed");
    }
}
public类读取器failedeventargs:EventArgs
{
公共读取器FailedEventArgs(IReader读取器,异常失败)
{
}
//[…此处有两个只读属性..]
}
公社工人
{
public event EventHandler ReaderFailed=委托{};
公共IEnumerable进程()
{
foreach(变量读取器在_读取器中)
{
尝试
{
返回reader.Read();
}
捕获(例外情况除外)
{
ReaderFailed(此,新ReaderFailedEventArgs(reader,ex);
}
}
//现在,这是一个真正的例外,因为用户希望获得数据
抛出新的InvalidOperationException(“所有读卡器失败”);
}
}

为事件分配一个空委托(
delegate{}
)允许我们使用该事件,而不必检查它是否为空(这也使事件线程安全)。

当应用程序应该继续时,调用方认为这些不是异常。异常应该总是中止

我会做一些类似.NET内部所做的事情,并有一个事件

public class ReaderFailedEventArgs : EventArgs
{
    public ReaderFailedEventArgs (IReader reader, Exception failure)
    {
    }

    // [.. Two read only properties here ..]
}

public class Worker
{
    public event EventHandler<ReaderFailedEventArgs> ReaderFailed = delegate{};

    public IEnumerable<Data> Process()
    {
        foreach (var reader in _readers)
        {
            try
            {
                return reader.Read();
            }
            catch (Exception ex)
            {
                ReaderFailed(this, new ReaderFailedEventArgs(reader, ex);
            }
        }

        // now, this is a real exception since user expects to get data
        throw new InvalidOperationException("All readers failed");
    }
}
public类读取器failedeventargs:EventArgs
{
公共读取器FailedEventArgs(IReader读取器,异常失败)
{
}
//[…此处有两个只读属性..]
}
公社工人
{
public event EventHandler ReaderFailed=委托{};
公共IEnumerable进程()
{
foreach(变量读取器在_读取器中)
{
尝试
{
返回reader.Read();
}
捕获(例外情况除外)
{
ReaderFailed(此,新ReaderFailedEventArgs(reader,ex);
}
}
//现在,这是一个真正的例外,因为用户希望获得数据
抛出新的InvalidOperationException(“所有读卡器失败”);
}
}

为事件分配一个空委托(
delegate{}
)允许我们使用事件,而不必检查它是否为空(它还使事件线程安全).

如果您只想收集所有异常,直到完成为止,您也可以收集它们并继续执行下一个操作,最后抛出一个
aggregateeexception
(请参阅)。如果只想在完成之前收集所有异常,也可以收集它们并继续执行下一个操作,最后抛出一个
aggregateeexception
(请参阅)。谢谢,这可以是一种方式。是否有任何方式可以通知异常不属于签名的部分?如事件。可以通过多种方式完成。如果是事件,则需要定义一个将返回事件的事件处理程序。谢谢,这可以是一种方式。是否有任何方式可以通知异常不属于签名的部分?如events。它可以通过任何方式完成。在事件的情况下,您需要定义一个将返回事件的事件处理程序。谢谢,这正是我需要的谢谢,这正是我需要的