相关疑难解决方法(0)

Dispose vs Dispose(bool)

我很困惑处置.我正在尝试让我的代码正确处理资源.所以我一直在将我的类设置为IDisposable(使用Dispose方法),确保调用Dispose方法.

但是现在FXCop告诉我很多关于Disposing = false和调用Dispose(false)的东西.

我没有看到一个带有bool的Dispose方法.我需要制作一个吗?如果是这样,为什么?为什么不在处理时调用一个方法呢?

我在这里看到了一些代码:http://msdn.microsoft.com/en-us/library/ms244737.aspx,它展示了如何制作一个带有bool的Disposing方法.它表示它适用于本地和管理资源. 但我认为处理的全部内容仅适用于非管理资源.

此外,FXCop抱怨的路线是这样的:

    ~OwnerDrawnPanel()
    {
        _font.Dispose();
    }
Run Code Online (Sandbox Code Playgroud)

它说:

CA1063:Microsoft.Design:修改'OwnerDrawnPanel .~ OwnerDrawnPanel()',以便它调用Dispose(false)然后返回.

但是Font上没有Dispose(bool)(我能找到).

把它们加起来:

为什么我需要Dispose(bool)?如果我这样做,为什么Font没有呢?因为它没有它,为什么FXCop要求我使用它?


感谢所有的好答案.我想我现在明白了.这是

答案就像我看到的那样:

处置"非管理"资源分为两类:

  1. 包含在托管类(即Bitmap,Font等)中的资源,但仍需要调用Dispose来正确清理它们.
  2. 您已分配的资源,即本机资源的表示(即需要发布的设备上下文)

Dispose(bool)用于表示两者之间的区别:

  1. 当直接在您的对象上调用Dispose时,您希望释放两种"非托管"资源.
  2. 当您的对象用于垃圾收集时,您不必担心第一种资源.垃圾收集器在清理它们时会处理它们.您只需要担心已分配的真实本机资源(如果有).

c# dispose

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

捕获SOAP请求到ASP.NET ASMX Web服务

考虑将传入的SOAP请求记录到ASP.NET ASMX Web服务的要求.任务是捕获发送到Web服务的原始XML.

需要记录传入消息以进行调试检查.该应用程序已经有自己的日志库,因此理想的用法是这样的:

//string or XML, it doesn't matter.
string incomingSoapRequest = GetSoapRequest();

Logger.LogMessage(incomingSoapRequest);
Run Code Online (Sandbox Code Playgroud)
  • 是否有任何简单的解决方案来捕获传入SOAP请求的原始XML?
  • 您将处理哪些事件来访问此对象和相关属性?
  • 无论如何IIS是否可以捕获传入的请求并推送到日志?

asp.net soap web-services asmx

30
推荐指数
3
解决办法
5万
查看次数

处理C#中嵌套的"using"语句

我注意到using我的代码中嵌套语句的级别最近有所增加.究其原因,可能是因为我使用越来越多的async/await格局,这往往增加了至少一个以上usingCancellationTokenSourceCancellationTokenRegistration.

那么,如何减少嵌套using,所以代码看起来不像圣诞树?之前已经提出了类似的问题,我想总结一下我从答案中学到的东西.

使用邻近using而不缩进.一个假的例子:

using (var a = new FileStream())
using (var b = new MemoryStream())
using (var c = new CancellationTokenSource())
{
    // ... 
}
Run Code Online (Sandbox Code Playgroud)

这可能有用,但通常会有一些代码using(例如,创建另一个对象可能为时过早):

// ... 
using (var a = new FileStream())
{
    // ... 
    using (var b = new MemoryStream())
    {
        // ... 
        using (var c = new CancellationTokenSource())
        {
            // ... 
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

将相同类型(或强制转换IDisposable)的对象组合成单个对象using,例如:

// …
Run Code Online (Sandbox Code Playgroud)

c#

30
推荐指数
3
解决办法
9896
查看次数

如何处理从Dispose抛出的异常?

最近,我正在研究一些关于没有处理的对象的棘手错误.

我在代码中找到了一些模式.据报道,有些m_foo没有被处理,而似乎SomeClass的所有实例都被处理掉了.

public class SomeClass: IDisposable
{
    void Dispose()
    {
       if (m_foo != null)
       {
          m_foo.Dispose();
       }
       if (m_bar != null)
       {
          m_bar.Dispose();
       }   
    }

    private Foo m_foo;

    private Bar m_bar;

}
Run Code Online (Sandbox Code Playgroud)

我怀疑Foo.Dispose可能会抛出异常,因此不会执行以下代码,因此不会释放m_bar.

由于Foo/Bar可能来自第三方,因此不保证不会抛出异常.

如果只使用try-catch包装所有Dispose调用,代码将变得笨拙.

处理这个问题的最佳做法是什么?

.net dispose idisposable

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

处理嵌套"using"语句时"Dispose"抛出的异常

显然,使用嵌套using语句时可能会丢失一些异常.考虑这个简单的控制台应用

using System;

namespace ConsoleApplication
{
    public class Throwing: IDisposable
    {
        int n;

        public Throwing(int n)
        {
            this.n = n;
        }

        public void Dispose()
        {
            var e = new ApplicationException(String.Format("Throwing({0})", this.n));
            Console.WriteLine("Throw: {0}", e.Message);
            throw e;
        }
    }

    class Program
    {
        static void DoWork()
        {
            // ... 
            using (var a = new Throwing(1))
            {
                // ... 
                using (var b = new Throwing(2))
                {
                    // ... 
                    using (var c = new Throwing(3))
                    {
                        // ... 
                    }
                }
            }
        } …
Run Code Online (Sandbox Code Playgroud)

c#

11
推荐指数
2
解决办法
1761
查看次数

在catch/finally块中抛出吞咽异常

通常我会遇到这样的情况:我必须吞下catch/ finallyblock中清理代码抛出的异常,以防止吞噬原始异常.

例如:

// Closing a file in Java
public void example1() throws IOException {
    boolean exceptionThrown = false;
    FileWriter out = new FileWriter(“test.txt”);
    try {
        out.write(“example”);
    } catch (IOException ex) {
        exceptionThrown = true;
        throw ex;
    } finally {
        try {
            out.close();
        } catch (IOException ex) {
            if (!exceptionThrown) throw ex;
            // Else, swallow the exception thrown by the close() method
            // to prevent the original being swallowed.
        }
    }
}

// Rolling back a transaction …
Run Code Online (Sandbox Code Playgroud)

c# java

10
推荐指数
2
解决办法
9928
查看次数

使用块吞咽异常

我有

void foo1()
{
   using(...){...}
}

void foo2()
{
   using(...){...}
}

void foo3()
{
   using(...){...}
}
Run Code Online (Sandbox Code Playgroud)

我有

void foo()
{
    ...
    backgroundWorker.DoWork += (s, ev) =>
                                           {
                                               try
                                               {
                                                   foo1();
                                                   foo2();
                                                   foo3();
                                               }
                                               catch (Exception ex)
                                               {
                                                   // log ex
                                               }
                                           };
      ...    
}
Run Code Online (Sandbox Code Playgroud)

我只是读到了using块吞下异常.它有一种优雅的方式来处理从异常foo1(),foo2()foo3()foo().我不想using在方法中的每个块内部使用try/catch .我确实偶然发现了这篇文章,建议使用扩展方法,但我只是检查是否有更好的方法.

仅供参考,网络断开导致using块内的逻辑抛出异常,这就是我在一个常见的地方尝试处理的问题.

谢谢,

c# exception-handling using-statement

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

在AsyncDispose中处理异常的正确方法

在切换到新的.NET Core 3的过程中IAsynsDisposable,我偶然发现了以下问题。

问题的核心:如果DisposeAsync引发异常,则此异常隐藏await using-block 内部引发的所有异常。

class Program 
{
    static async Task Main()
    {
        try
        {
            await using (var d = new D())
            {
                throw new ArgumentException("I'm inside using");
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message); // prints I'm inside dispose
        }
    }
}

class D : IAsyncDisposable
{
    public async ValueTask DisposeAsync()
    {
        await Task.Delay(1);
        throw new Exception("I'm inside dispose");
    }
}
Run Code Online (Sandbox Code Playgroud)

被捕获的是AsyncDispose-exception(如果引发了),而内部异常await using只有在AsyncDispose未引发的情况下才被捕获。

但是,我还是更喜欢它:await using …

c# async-await iasyncdisposable

6
推荐指数
2
解决办法
112
查看次数

将异步操作转换为异步函数委托,保留同步异常传递

我想将异步操作委托转换为返回指定值的异步函数委托.我想出了一个扩展方法:

public static Func<Task<TResult>> Return<TResult>(this Func<Task> asyncAction, TResult result)
{
    ArgumentValidate.NotNull(asyncAction, nameof(asyncAction));

    return async () =>
    {
        await asyncAction();
        return result;
    };
}
Run Code Online (Sandbox Code Playgroud)

但是,我的扩展方法是错误的,因为从操作委托同步传递的异常现在从函数委托异步传递.具体来说:

Func<Task> asyncAction = () => { throw new InvalidOperationException(); };
var asyncFunc = asyncAction.Return(42);
var task = asyncFunc();   // exception should be thrown here
await task;               // but instead gets thrown here
Run Code Online (Sandbox Code Playgroud)

有没有办法以同步异常继续同步传递的方式创建此包装器?是ContinueWith要走的路?

更新:同步抛出异常的异步操作的具体示例:

public static Task WriteAllBytesAsync(string filePath, byte[] bytes)
{
    if (filePath == null)
        throw new ArgumentNullException(filePath, nameof(filePath));
    if (bytes == …
Run Code Online (Sandbox Code Playgroud)

.net c# asynchronous task async-await

3
推荐指数
1
解决办法
283
查看次数