相关疑难解决方法(0)

当没有抛出异常时,try/catch块是否会损害性能?

在与Microsoft员工进行代码审查期间,我们在try{}块中遇到了大量代码.她和IT代表建议这可能会影响代码的性能.事实上,他们建议大多数代码应该在try/catch块之外,并且只应该检查重要的部分.微软员工补充说,即将发布的白皮书警告不要使用不正确的try/catch块.

我环顾四周,发现它可以影响优化,但它似乎只适用于范围之间共享变量.

我不是在询问代码的可维护性,甚至不是在处理正确的异常(有问题的代码需要重新分解,毫无疑问).我也没有提到使用流量控制的异常,这在大多数情况下显然是错误的.这些都是重要的问题(有些更重要),但不是重点.

如果抛出异常,try/catch块如何影响性能?

c# performance try-catch

261
推荐指数
12
解决办法
7万
查看次数

为什么检查字典是否包含密钥更快,而不是在不包含异常的情况下捕获异常?

想象一下代码:

public class obj
{
    // elided
}

public static Dictionary<string, obj> dict = new Dictionary<string, obj>();
Run Code Online (Sandbox Code Playgroud)

方法1

public static obj FromDict1(string name)
{
    if (dict.ContainsKey(name))
    {
        return dict[name];
    }
    return null;
}
Run Code Online (Sandbox Code Playgroud)

方法2

public static obj FromDict2(string name)
{
    try
    {
        return dict[name];
    }
    catch (KeyNotFoundException)
    {
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

我很好奇这两个函数的性能是否存在差异,因为第一个函数应该比第二个函数更低 - 假设它需要在字典包含值时检查两次,而第二个函数确实只需要访问字典曾经但是WOW,它实际上是相反的:

循环1 000 000个值(现有10万个,不存在90 000个):

第一个功能:306毫秒

第二功能:20483毫秒

这是为什么?

编辑:你可以在下面这个问题的评论中注意到,如果有0个非现有密钥,第二个函数的性能实际上略好于第一个函数.但是,一旦存在至少一个或多个非现有密钥,则第二个密钥的性能会迅速下降.

c# performance dictionary

234
推荐指数
2
解决办法
13万
查看次数

尝试/终于在C#中的开销?

我们已经看到很多关于何时以及为何使用try/ catchtry/ catch/的问题finally.我知道try/ 肯定有一个用例finally(特别是因为它是using语句实现的方式).

我们还看到了有关try/catch和异常开销的问题.

然而,我所链接的问题并没有谈到JUST try-finally的开销.

假设try块中发生的任何事情都没有异常,那么确保finally语句在离开try块时执行的开销是多少(有时是从函数返回)?

再一次,我只询问try/ finally,不catch,不抛出异常.

谢谢!

编辑:好的,我将尝试更好地展示我的用例.

我应该使用哪个,DoWithTryFinally或者DoWithoutTryFinally

public bool DoWithTryFinally()
{
  this.IsBusy = true;

  try
  {
    if (DoLongCheckThatWillNotThrowException())
    {
      this.DebugLogSuccess();
      return true;
    }
    else
    {
      this.ErrorLogFailure();
      return false;
    }
  }
  finally
  {
    this.IsBusy = false;
  }
}

public bool DoWithoutTryFinally()
{
  this.IsBusy …
Run Code Online (Sandbox Code Playgroud)

.net c# performance try-finally

71
推荐指数
6
解决办法
5276
查看次数

以编程方式转储调用堆栈

寻找一种方法,以便在遇到一段代码时以编程方式转储调用堆栈和.net Win Forms应用程序.它之前我没有遇到过但会节省一些调试时间.

更新:忘记添加,这将增加应用程序的开销,即它会大大减慢它的速度.

.net c# debugging

33
推荐指数
2
解决办法
2万
查看次数

要求许可或道歉?

我来自python背景,经常说道歉比要求许可更容易道歉.特别给出了两个片段:

if type(A) == int:
  do_something(A)
else:
  do_something(int(A))

try:
  do_something(A)
except TypeError:
  do_something(int(A))
Run Code Online (Sandbox Code Playgroud)

然后在大多数使用场景下,当A通常是一个整数时假设第二个会更快(假设do_something需要一个整数作为输入并且会相当迅速地提高它的异常),因为你从每个执行循环中丢失了逻辑测试,代价是更多昂贵的例外,但不那么频繁.

我想要检查的是在C#中这是否正确,或者逻辑测试与异常相比是否足够快以使其成为一个小角落?

哦,我只对发布性能感兴趣,而不是调试.


好吧,我的例子太模糊了试试这个:

天真的解决方案:

return float(A) % 20 # coerse A to a float so it'll only fail if we actually don't
                     # have anything that can be represented as a real number.
Run Code Online (Sandbox Code Playgroud)

逻辑解决方案:

if isinstance(A, Number): # This is cheaper because we're not creating a new
    return A % 20         # object unless we really have to.
else:
    return float(A) %20
Run Code Online (Sandbox Code Playgroud)

基于异常的解决方案:

try: # Now …
Run Code Online (Sandbox Code Playgroud)

c# python performance

12
推荐指数
3
解决办法
992
查看次数

如何在C#中实现正确的插件?

我正在尝试为我的游戏添加插件,我正在尝试实现的是:

  • 插件将是我的或第三方的,所以我想要一个解决方案,插件崩溃不会意味着主应用程序崩溃.

  • 插件的方法经常被调用(例如,因为绘制了游戏对象).

到目前为止我发现了什么:

你能评论一下我的发现吗?新方法也受到欢迎!谢谢!

c# plugins

9
推荐指数
1
解决办法
1658
查看次数

例外与返回代码:我们是否会丢失一些东西(同时获得其他东西)?

我的问题很模糊:o) - 但这是一个例子:

当我编写C代码时,我能够在出现故障时记录计数器的值:

   <...>
   for ( int i = 0 ; i < n ; i++ )
      if ( SUCCESS != myCall())
         Log( "Failure, i = %d", i );
   <...>
Run Code Online (Sandbox Code Playgroud)

现在,使用异常,我得到这个:

  try
   {
      <...>
      for ( int i = 0 ; i < n ; i++ )
         myCall();
      <...>
   }
   catch ( Exception exception )
   {
      Log( "Failure ! Maybe in myCall() ? Don't know. i's value ? No clue." );
   }
Run Code Online (Sandbox Code Playgroud)

当然,可以在try/catch语句之外声明"i"(这就是我正在做的事情).但我不喜欢它 - 我喜欢声明变量在哪里使用,而不是之前.

但也许我在这里遗漏了一些东西.你有什么优雅的解决方案吗?

预先感谢 !西尔万.

ADDED:myCall()是一个不起眼的API调用 …

c# exception return-code

8
推荐指数
4
解决办法
3980
查看次数

何时引发异常或返回 null?

我在数据访问层有一些功能

public Order RetrieveById(int id)
public List<Order> RetrieveByStatus(OrderStatus status)
Run Code Online (Sandbox Code Playgroud)

现在我对异常引发有点困惑。

对于 RetrieveById 函数,小于 1 的 id 是无效 id,因此我想引发异常。我想为数据库中不存在的 Id 返回 null。然后感觉我太复杂了。

对于 RetrieveByStatus,当数据库中没有该状态的数据时,我想返回一个空列表。

但是我看到有些人在 RetrieveById 无法返回任何内容时引发异常,但 RetrieveByStatus 在没有记录时不应引发异常,或者应该吗?

有人可以帮我澄清这些概念吗?

c# exception

6
推荐指数
1
解决办法
4689
查看次数

在异常处理方面删除文件的最有效方法是什么?

MSDN告诉我们,当你调用"File.Delete(path);"时 在不存在的文件上生成异常.

在执行删除之前调用delete方法并使用try/catch块来避免错误或验证文件的存在会更有效吗?

我倾向于认为避免try/catch块更好.当您知道如何检查错误时,为什么会发生错误.

无论如何,这里是一些示例代码:

// Option 1: Just delete the file and ignore any exceptions

/// <summary>
/// Remove the files from the local server if the DeleteAfterTransfer flag has been set
/// </summary>
/// <param name="FilesToSend">a list of full file paths to be removed from the local server</param>
private void RemoveLocalFiles(List<string> LocalFiles)
{
    // Ensure there is something to process
    if (LocalFiles != null && LocalFiles.Count > 0 && m_DeleteAfterTransfer == true)
    {
        foreach (string file in LocalFiles) …
Run Code Online (Sandbox Code Playgroud)

c# file-io exception-handling

5
推荐指数
1
解决办法
5285
查看次数

异常处理.捕获多长时间?

可能重复:
.NET异常有多慢?

是否存在抛出异常并立即捕获的开销?这有什么区别

void DoSomething(object basic)
{
    try
    {
       if (basic == null)
         throw new NullReferenceException("Any message");
       else
       {
         //...
       }
    }
    catch (Exception error)
    {
       _logger.WriteLog(error);
    }
}
Run Code Online (Sandbox Code Playgroud)

这个(这里我们不抛出异常):

void DoSomething(object basic)
{
    try
    {
        if (basic == null)
        {
            _logger.WriteLog(new NullReferenceException("Any message");
            return;
        }
        else
        {
         ...
        }
    }
    catch (Exception error)
    {
        _logger.WriteLog(error);
    }
}
Run Code Online (Sandbox Code Playgroud)

第二个片段会更快吗?

此外,我想知道为什么一个解决方案比另一个更快.

c# exception-handling exception

5
推荐指数
1
解决办法
1155
查看次数

如何在try-catch块中正确放置语句?

我需要一个接一个地执行大量语句,并且我需要在sigle语句抛出异常时,程序流继续执行下一个语句,例如:

double a = Double.Parse("2.5");
double b = Double.Parse("ADFBBG");
Geometry g = Geometry.Parse("M150,0L75,200 225,200z");
Run Code Online (Sandbox Code Playgroud)

所有语句都必须执行,所以我需要一种级联的try-catch块:

double a, b;
Geometry g;

try
{
   a = Double.Parse("2.5");
}
catch
{}

try
{
   b = Double.Parse("ADFBBG");
}
catch
{}

try
{
   g = Geometry.Parse("M150,0L75,200 225,200z");
}
catch
{}
Run Code Online (Sandbox Code Playgroud)

显然,这不是编写程序的最优雅方式.有更好的方法(更优雅,不会显着降低性能)?

我尝试Func<TResult>以这种方式使用委托:

我写了以下方法:

T Try<T>(Func<T> func)
{
    try
    {
        return func();
    }
    catch
    {
        return default(T);
    }
}
Run Code Online (Sandbox Code Playgroud)

所以我可以像这样使用它:

double x = Try(() => Double.Parse("77"));
Geometry g = Try(() => …
Run Code Online (Sandbox Code Playgroud)

c# exception try-catch func

5
推荐指数
1
解决办法
271
查看次数

我应该总是检查返回值是否为空

如果在一个班级A:

Class A
    public List<string> getValues
Run Code Online (Sandbox Code Playgroud)

如果我想调用该方法,我应该总是检查返回值是否为空?虽然我不认为它可能是null(应该是一个空列表).即

Class B
    public void GetSomething
        foreach (var thing in A.getValues)
            //do something....
Run Code Online (Sandbox Code Playgroud)

要么

Class B
    public void GetSomething
        var things = A.getValues;
        if (things != null)
        foreach (var thing in things)
            //then doing something....
Run Code Online (Sandbox Code Playgroud)

提出这个问题的原因是,当我编写单元测试时,我在A类中使该方法返回null而不是空列表,但是如果它发生的话我在现实生活中不知道,因为如果它可以为null那么它总是好的检查而不是尝试捕获异常,哪一个更合适?

c# null

2
推荐指数
1
解决办法
183
查看次数