对象 'iCrypt' 可以被处置多次
Object 'iCrypt' can be disposed more than once
我看到了几个关于这个问题的问题。例如:
"Object can be disposed of more than once" error
但我不太清楚我应该用我的代码做什么。我从代码分析中得到的警告是:
1>D:\My Programs17\PTSTools\PTSTools\PTSTools.cs(81): warning
CA2202: Microsoft.Usage : Object 'iCrypt' can be disposed more than
once in method 'PTSToolsClass.Crypt(string, string, bool)'. To avoid
generating a System.ObjectDisposedException you should not call
Dispose more than one time on an object.: Lines: 81
有问题的方法:
private string Crypt(string strData, string strPassword, bool bEncrypt)
{
byte[] u8Salt = new byte[] { ... };
PasswordDeriveBytes iPass = new PasswordDeriveBytes(strPassword, u8Salt);
Rijndael iAlg = Rijndael.Create();
iAlg.Key = iPass.GetBytes(32);
iAlg.IV = iPass.GetBytes(16);
ICryptoTransform iTrans = (bEncrypt) ? iAlg.CreateEncryptor() : iAlg.CreateDecryptor();
MemoryStream iMem = new MemoryStream();
CryptoStream iCrypt = new CryptoStream(iMem, iTrans, CryptoStreamMode.Write);
byte[] u8Data;
if (bEncrypt)
u8Data = Encoding.Unicode.GetBytes(strData);
else
u8Data = Convert.FromBase64String(strData);
try
{
iCrypt.Write(u8Data, 0, u8Data.Length);
iCrypt.Close();
if (bEncrypt)
return Convert.ToBase64String(iMem.ToArray());
else
return Encoding.Unicode.GetString(iMem.ToArray());
}
catch
{
return null;
}
finally
{
iCrypt.Close();
}
}
谁能解释一下为什么我会在 finally
行代码中收到此警告?
谢谢。
更新:
根据评论,我将其更改为:
private string Crypt(string strData, string strPassword, bool bEncrypt)
{
byte[] u8Salt = new byte[] { ... };
PasswordDeriveBytes iPass = new PasswordDeriveBytes(strPassword, u8Salt);
Rijndael iAlg = Rijndael.Create();
iAlg.Key = iPass.GetBytes(32);
iAlg.IV = iPass.GetBytes(16);
ICryptoTransform iTrans = (bEncrypt) ? iAlg.CreateEncryptor() : iAlg.CreateDecryptor();
MemoryStream iMem = new MemoryStream();
using (CryptoStream iCrypt = new CryptoStream(iMem, iTrans, CryptoStreamMode.Write))
{
byte[] u8Data;
if (bEncrypt)
u8Data = Encoding.Unicode.GetBytes(strData);
else
u8Data = Convert.FromBase64String(strData);
try
{
iCrypt.Write(u8Data, 0, u8Data.Length);
iCrypt.Close();
if (bEncrypt)
return Convert.ToBase64String(iMem.ToArray());
else
return Encoding.Unicode.GetString(iMem.ToArray());
}
catch
{
return null;
}
}
}
但我现在有这些警告:
1>D:\My Programs17\PTSTools\PTSTools\PTSTools.cs(77): warning CA2202: Microsoft.Usage : Object 'iCrypt' can be disposed more than once in method 'PTSToolsClass.Crypt(string, string, bool)'. To avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object.: Lines: 77
1>D:\My Programs17\PTSTools\PTSTools\PTSTools.cs(77): warning CA2202: Microsoft.Usage : Object 'iMem' can be disposed more than once in method 'PTSToolsClass.Crypt(string, string, bool)'. To avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object.: Lines: 77
它现在不喜欢 catch 块。
更新:
了解:
private string Crypt(string strData, string strPassword, bool bEncrypt)
{
byte[] u8Salt = new byte[] { 0x26, 0x19, 0x81, 0x4E, 0xA0, 0x6D, 0x95, 0x34, 0x26, 0x75, 0x64, 0x05, 0xF6 };
PasswordDeriveBytes iPass = new PasswordDeriveBytes(strPassword, u8Salt);
Rijndael iAlg = Rijndael.Create();
iAlg.Key = iPass.GetBytes(32);
iAlg.IV = iPass.GetBytes(16);
ICryptoTransform iTrans = (bEncrypt) ? iAlg.CreateEncryptor() : iAlg.CreateDecryptor();
MemoryStream iMem = new MemoryStream();
using (CryptoStream iCrypt = new CryptoStream(iMem, iTrans, CryptoStreamMode.Write))
{
byte[] u8Data;
if (bEncrypt)
u8Data = Encoding.Unicode.GetBytes(strData);
else
u8Data = Convert.FromBase64String(strData);
try
{
iCrypt.Write(u8Data, 0, u8Data.Length);
if (bEncrypt)
return Convert.ToBase64String(iMem.ToArray());
else
return Encoding.Unicode.GetString(iMem.ToArray());
}
catch
{
return null;
}
}
}
您正在调用 iCrypt.Close();两次,从 try 语句中删除调用,你会没事的。
代码分析的信息很清楚。您的代码处理(关闭)iCrypt 两次。一次在 try 块中,一次在 finally 块中。删除 try 块中的 iCrypt.Close();
行(在 iCrypt.Write(...)
和 if(...)
之间,警告将消失。
更好的方法是使用块:
using (CryptoStream iCrypt = new CryptoStream(...)) {
.... // your code without the finally block
}
using 将调用 iCrypt.Close() 而不管块内是否抛出异常。
Because the finally
block of a try-(catch-)finally
block is always executed,分析器看到这个:
try
{
iCrypt.Close();
}
finally
{
iCrypt.Close();
}
然后它正确地推断出这些调用可以连续发生,导致 ObjectDisposedException
在第二次调用中被抛出。
因此:您不需要 try
块中的 iCrypt.Close()
,因为它总是会在 finally
中关闭,无论是否发生异常。
我看到了几个关于这个问题的问题。例如:
"Object can be disposed of more than once" error
但我不太清楚我应该用我的代码做什么。我从代码分析中得到的警告是:
1>D:\My Programs17\PTSTools\PTSTools\PTSTools.cs(81): warning CA2202: Microsoft.Usage : Object 'iCrypt' can be disposed more than once in method 'PTSToolsClass.Crypt(string, string, bool)'. To avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object.: Lines: 81
有问题的方法:
private string Crypt(string strData, string strPassword, bool bEncrypt)
{
byte[] u8Salt = new byte[] { ... };
PasswordDeriveBytes iPass = new PasswordDeriveBytes(strPassword, u8Salt);
Rijndael iAlg = Rijndael.Create();
iAlg.Key = iPass.GetBytes(32);
iAlg.IV = iPass.GetBytes(16);
ICryptoTransform iTrans = (bEncrypt) ? iAlg.CreateEncryptor() : iAlg.CreateDecryptor();
MemoryStream iMem = new MemoryStream();
CryptoStream iCrypt = new CryptoStream(iMem, iTrans, CryptoStreamMode.Write);
byte[] u8Data;
if (bEncrypt)
u8Data = Encoding.Unicode.GetBytes(strData);
else
u8Data = Convert.FromBase64String(strData);
try
{
iCrypt.Write(u8Data, 0, u8Data.Length);
iCrypt.Close();
if (bEncrypt)
return Convert.ToBase64String(iMem.ToArray());
else
return Encoding.Unicode.GetString(iMem.ToArray());
}
catch
{
return null;
}
finally
{
iCrypt.Close();
}
}
谁能解释一下为什么我会在 finally
行代码中收到此警告?
谢谢。
更新:
根据评论,我将其更改为:
private string Crypt(string strData, string strPassword, bool bEncrypt)
{
byte[] u8Salt = new byte[] { ... };
PasswordDeriveBytes iPass = new PasswordDeriveBytes(strPassword, u8Salt);
Rijndael iAlg = Rijndael.Create();
iAlg.Key = iPass.GetBytes(32);
iAlg.IV = iPass.GetBytes(16);
ICryptoTransform iTrans = (bEncrypt) ? iAlg.CreateEncryptor() : iAlg.CreateDecryptor();
MemoryStream iMem = new MemoryStream();
using (CryptoStream iCrypt = new CryptoStream(iMem, iTrans, CryptoStreamMode.Write))
{
byte[] u8Data;
if (bEncrypt)
u8Data = Encoding.Unicode.GetBytes(strData);
else
u8Data = Convert.FromBase64String(strData);
try
{
iCrypt.Write(u8Data, 0, u8Data.Length);
iCrypt.Close();
if (bEncrypt)
return Convert.ToBase64String(iMem.ToArray());
else
return Encoding.Unicode.GetString(iMem.ToArray());
}
catch
{
return null;
}
}
}
但我现在有这些警告:
1>D:\My Programs17\PTSTools\PTSTools\PTSTools.cs(77): warning CA2202: Microsoft.Usage : Object 'iCrypt' can be disposed more than once in method 'PTSToolsClass.Crypt(string, string, bool)'. To avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object.: Lines: 77
1>D:\My Programs17\PTSTools\PTSTools\PTSTools.cs(77): warning CA2202: Microsoft.Usage : Object 'iMem' can be disposed more than once in method 'PTSToolsClass.Crypt(string, string, bool)'. To avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object.: Lines: 77
它现在不喜欢 catch 块。
更新:
了解:
private string Crypt(string strData, string strPassword, bool bEncrypt)
{
byte[] u8Salt = new byte[] { 0x26, 0x19, 0x81, 0x4E, 0xA0, 0x6D, 0x95, 0x34, 0x26, 0x75, 0x64, 0x05, 0xF6 };
PasswordDeriveBytes iPass = new PasswordDeriveBytes(strPassword, u8Salt);
Rijndael iAlg = Rijndael.Create();
iAlg.Key = iPass.GetBytes(32);
iAlg.IV = iPass.GetBytes(16);
ICryptoTransform iTrans = (bEncrypt) ? iAlg.CreateEncryptor() : iAlg.CreateDecryptor();
MemoryStream iMem = new MemoryStream();
using (CryptoStream iCrypt = new CryptoStream(iMem, iTrans, CryptoStreamMode.Write))
{
byte[] u8Data;
if (bEncrypt)
u8Data = Encoding.Unicode.GetBytes(strData);
else
u8Data = Convert.FromBase64String(strData);
try
{
iCrypt.Write(u8Data, 0, u8Data.Length);
if (bEncrypt)
return Convert.ToBase64String(iMem.ToArray());
else
return Encoding.Unicode.GetString(iMem.ToArray());
}
catch
{
return null;
}
}
}
您正在调用 iCrypt.Close();两次,从 try 语句中删除调用,你会没事的。
代码分析的信息很清楚。您的代码处理(关闭)iCrypt 两次。一次在 try 块中,一次在 finally 块中。删除 try 块中的 iCrypt.Close();
行(在 iCrypt.Write(...)
和 if(...)
之间,警告将消失。
更好的方法是使用块:
using (CryptoStream iCrypt = new CryptoStream(...)) {
.... // your code without the finally block
}
using 将调用 iCrypt.Close() 而不管块内是否抛出异常。
Because the finally
block of a try-(catch-)finally
block is always executed,分析器看到这个:
try
{
iCrypt.Close();
}
finally
{
iCrypt.Close();
}
然后它正确地推断出这些调用可以连续发生,导致 ObjectDisposedException
在第二次调用中被抛出。
因此:您不需要 try
块中的 iCrypt.Close()
,因为它总是会在 finally
中关闭,无论是否发生异常。