I see this:
using (StreamWriter sw = new StreamWriter("file.txt"))
{
// d0 w0rk s0n
}
Everything I try to find info on is does not explain what this doing, and instead gives me stuff about namespaces.
You want to check out documentation for the using statement (instead of the using directive which is about namespaces).
Basically it means that the block is transformed into a try/finally block, and sw.Dispose() gets called in the finally block (with a suitable nullity check).
You can use a using statement wherever you deal with a type implementing IDisposable - and usually you should use it for any disposable object you take responsibility for.
A few interesting bits about the syntax:
You can acquire multiple resources in one statement:
using (Stream input = File.OpenRead("input.txt"),
output = File.OpenWrite("output.txt"))
{
// Stuff
}
You don't have to assign to a variable:
// For some suitable type returning a lock token etc
using (padlock.Acquire())
{
// Stuff
}
You can nest them without braces; handy for avoiding indentation
using (TextReader reader = File.OpenText("input.txt"))
using (TextWriter writer = File.CreateText("output.txt"))
{
// Stuff
}
The using construct is essentially a syntactic wrapper around automatically calling dispose on the object within the using. For example your above code roughly translates into the following
StreamWriter sw = new StreamWriter("file.text");
try {
// do work
} finally {
if ( sw != null ) {
sw.Dispose();
}
}
Your question is answered by section 8.13 of the specification.
Here you go: http://msdn.microsoft.com/en-us/library/yh598w02.aspx
Basically, it automatically calls the Dispose member of an IDisposable interface at the end of the using scope.
check this Using statement
Related
I need to do serialization and deserialization using below code. But always i am getting "Dynamic type is not a contract-type" error while serializing. I am stuck with this. I need to achieve this someway Can somebody help me on this?
using ProtoBuf;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
namespace ProtoSerialization
{
class Program
{
static void Main(string[] args)
{
try
{
byte[] arr;
ClassA obj = new ClassA();
obj.ColumnList = new List<int> {1 };
using (var stream = new MemoryStream())
{
ProtoBuf.Serializer.Serialize(stream, obj);
arr = stream.ToArray();
}
using(var stream=new MemoryStream(arr))
{
var result = Serializer.Deserialize(typeof(ClassA), stream);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.ReadKey();
}
}
}
[ProtoContract]
public class ClassA
{
[ProtoMember(1,DynamicType =true)]
public IList ColumnList;
}
}
I strongly advise against using the dynamic feature, here or elsewhere. It is deprecated in V3, probably permanently. It looks like what you really want here is something like a Value from struct.proto. This doesn't have inbuilt support in protobuf-net currently, but I'll probably add it soon. As for now: I'd probably advise using an array of a type that has those things as fields. If you make the layout look like Value does, in terms of the field numbers, it should be directly swappable later.
Mostly copied from question about protobuf dynamic array.
The documentation for dynamic arrays state:
DynamicType - stores additional Type information with the type (by default it includes the AssemblyQualifiedName, although this can be controlled by the user). This makes it possible to serialize weak models, i.e. where object is used for property members, however currently this is limited to contract types (not primitives), and does not work for types with inheritance (these limitations may be removed at a later time). Like with AsReference, this uses a very different layout format
You have a primitive, therefore you can not use DynamicType. As explained in the error message you got.
A workaround could be to wrap the primitives you want to store in another type with a defined contract.
I have a series of settings being written out by an XMLWriter in C#. Here's some code:
try
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.IndentChars = (" ");
using (writer = XmlWriter.Create("PCOB2NET.XML", settings))
{
// Write XML data.
writer.WriteStartElement("PowerCOBOL2NETMigration");
writer.WriteStartElement("config");
writer.WriteElementString("VSVersion", selectedVSver);
writer.WriteElementString("path2SelectedVSVerProjects", path2SelectedVSVerProjects);
if (path2VSoverridden)
writer.WriteElementString("path2VSoverridden", "true");
else
writer.WriteElementString("path2VSoverridden", "false");
writer.WriteElementString("path2PRCfile", path2PRCfile);
writer.WriteElementString("path2XMLfile", path2XMLfile);
writer.WriteElementString("path2VSProject", path2VSProject);
... and so on.
My problem is that if there is an Exception (like a null field, for instance) it goes to the catch block and reports the exception as we would expect, but I don't know WHICH field it was writing at the time.
My question:
Is there any way I can get the current string being written, when an Exception occurs? I searched the web without success and I looked through every property and method of XMLWriter but I can't find a way to do it. Is there maybe a certain type of Exception trap that will give it to me? Any help or thoughts appreciated.
Try xml linq which is a new Net Library for reading and writing xml
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
string selectedVSver = "";
string path2SelectedVSVerProjects = "";
Boolean path2VSoverridden = true;
string path2PRCfile = "";
string path2XMLfile = "";
string path2VSProject = "";
XDocument doc = new XDocument();
XElement powerCOBOL2NETMigration = new XElement("PowerCOBOL2NETMigration", new object[] {
new XElement("config", new object[] {
new XElement("VSVersion", selectedVSver),
new XElement("path2SelectedVSVerProjects", path2SelectedVSVerProjects),
new XElement("path2VSoverridden", path2VSoverridden),
new XElement("path2PRCfile", path2PRCfile),
new XElement("path2XMLfile", path2XMLfile),
new XElement("path2VSProject", path2VSProject)
})
});
doc.Add(powerCOBOL2NETMigration);
doc.Save(FILENAME);
}
}
}
The simplest approach is to wrap small helper methods around XmlWriter.WriteStartElement etc. and catch your exceptions there.
It turns out I was looking for a solution at the wrong end of the problem. Instead of puzzling over XMLWriter, what I SHOULD have done was investigate the EXCEPTION.
(I did do this but only for the Exception Class, I needed to look further.) The problem looked like it could be easily solved by nesting some exception catch blocks, so:
catch (ArgumentNullException anEx)
{
// retrieve the offending field name from anEX...
badField = anEx.ParamName;
...
}
catch (ArgumentException aEx)
{
// retrieve the offending field name from aEX...
badField = aEx.ParamName;
...
}
catch (Exception ex)
{
...
However, I was misled by the "ParamName" which does not mean what I thought it did... This always returned null and I was no better off.
After spending a number of hours reading everything I could about Exception handling in C#, I am much better informed, but no wiser. I can't find a solution with the Framework so I have little recourse but to push all the settings through a method which will do the actual write and trap any exception at that moment, with the offending field available as it will have been passed into that method.
I think this inelegant, but I can't spend more time on it. Many thanks to all who responded and those who thought about responding... :-) I'll leave this open in case somebody really has a solution, for a few days.
I want to populate this type of using statement through Roslyn.
Using(var logger = new MethodLogger("someparam"))
{
}
How can I generate it..
I am trying this SyntaxFactory.UsingStatement
For stuff like this I use roslynquoter. It generates roslyn calls out of C# code. For your case it returns something like this:
SyntaxFactory
.UsingStatement(SyntaxFactory.Block()/* the code inside the using block */)
.WithDeclaration(SyntaxFactory
.VariableDeclaration(SyntaxFactory.IdentifierName("var"))
.WithVariables(SyntaxFactory.SingletonSeparatedList(SyntaxFactory
.VariableDeclarator(SyntaxFactory.Identifier("logger"))
.WithInitializer(SyntaxFactory.EqualsValueClause(SyntaxFactory
.ObjectCreationExpression(SyntaxFactory.IdentifierName(#"MethodLogger"))
.WithArgumentList(/* arguments for MethodLogger ctor */)))
I inherited the following code:
using (var dataAccessConnection = da.GetConnection()) //no opening curly brace here
using (var command = new SqlCommand(sql, dataAccessConnection.Connection))
{
command.CommandType = CommandType.Text;
using (var sqlDataReader = command.ExecuteReader(CommandBehavior.CloseConnection))
{
while (sqlDataReader.Read())
{
rueckgabe.Add(new Myclass
{
Uid = Guid.NewGuid(),
ImportVersionUid = versionUid,
MyProperty = Convert.ToInt32(sqlDataReader["MyProperty"])
});
}
}
command.Connection.Close();
dataAccessConnection.Connection.Close();
}
Looking at the code I expexted an opening curly brace after the using clause.
The code compiles and does what it is expected to do. The application behaves unpredictable. At some time it cant access the Database server.
Does this code make sense? Does dataAccessConnection have the rigth scope?
Beginning with C# 8.0, the using keyword can be used as an attribute in the variable declarations of disposable objects (Reference). The semantics is as you would expect -- the objects are auto-disposed at the end of the scope.
public class Disposable : IDisposable
{
string name;
public Disposable(string name)
{
this.name = name;
}
public void Dispose()
{
Console.WriteLine(name + " disposed");
}
public void Identify()
{
Console.WriteLine(name);
}
static void Main(string[] args)
{
using Disposable d1 = new Disposable("Using 1");
Disposable d2 = new Disposable("No Using 2");
using Disposable d3 = new Disposable("Using 3");
Disposable d4 = new Disposable("No Using 4");
d1.Identify();
d2.Identify();
d3.Identify();
d4.Identify();
}
}
Output
Using 1
No Using 2
Using 3
No Using 4
Using 3 disposed
Using 1 disposed
using statements without explicit curly braces apply only to the following statement.
using (Idisp1)
// use it
// it's disposed
Thus, when chained, they work the same way. The second using here acts as a single statement.
using (Idisp1)
using (Idisp2)
{
}
Commenter stakx suggested that formatting to make it clear how the compiler reads the using blocks. In reality, these would usually be formatted as the OP encountered:
using (Idisp1)
using (Idisp2)
{
}
That is equivalent to this:
using (Idisp1)
{
using (Idisp2)
{
}
}
Notice that the first at the top is always the last to dispose. Thus, in all previous examples, Idisp2.Dispose() is called before Idisp1.Dispose(). That isn't relevant in many cases where you would do something like this, but I believe you should always be aware of what your code will do and make the informed decision not to care.
An example of this is when reading a web page:
HttpWebRequest req = ...;
using (var resp = req.GetResponse())
using (var stream = resp.GetResponseStream())
using (var reader = new StreamReader(stream))
{
TextBox1.Text = reader.ReadToEnd(); // or whatever
}
We get the response, get the stream, get the reader, read the stream, dispose the reader, dispose the stream, and finally, dispose the response.
Note, as commenter Nikhil Agrawal pointed out, that this is a language feature regarding blocks that is not specific to the using keyword. For example, the same applies to if blocks:
if (condition)
// may or may not execute
// definitely will execute
Versus
if (condition1)
if (condition2)
// will execute if both are true
// definitely will execute
Although you should never, of course, use if statements this way as it's dreadful to read, but I thought it'd help you understand the using case. I'm personally very okay with chaining using blocks.
The C# language specification (Version 5) describes a using statement as:
using-statement:
using ( resource-acquisition ) embedded-statement
That is:
The using statement obtains one or more resources, executes a statement, and then disposes of the resource.
(My emphasis)
So, how then do we end up using it with curly braces? Because the definition of embedded-statement is:
embedded-statement:
block
empty-statement
expression-statement
selection-statement
iteration-statement
jump-statement
try-statement
checked-statement
unchecked-statement
lock-statement
using-statement
yield-statement
And:
The embedded-statement nonterminal is used for statements that appear within other statements
And finally, we discover that block is defined as:
A block permits multiple statements to be written in contexts where a single statement is allowed.
block:
{ statement-listopt }
So basically, curly braces can always be used to take a situation where a single statement is accepted and to instead have multiple statements.
It just so happens that, almost always, we do want to make use of more than one statement, and so the curly-braces tend to be seen as part of if, using, etc statements. Whereas, in fact, they're a separate part of the language.
I am using the following code under ASP.NET 4.0 framework to obtain the version of MSI file from a web app:
string strVersion = "";
try
{
Type InstallerType;
WindowsInstaller.Installer installer;
InstallerType = Type.GetTypeFromProgID("WindowsInstaller.Installer");
installer = (WindowsInstaller.Installer)Activator.CreateInstance(InstallerType);
WindowsInstaller.Database db = installer.OpenDatabase(strMSIFilePath, 0);
WindowsInstaller.View dv = db.OpenView("SELECT `Value` FROM `Property` WHERE `Property`='ProductVersion'");
WindowsInstaller.Record record = null;
dv.Execute(record);
record = dv.Fetch();
strVersion = record.get_StringData(1).ToString();
dv.Close();
//db.Commit();
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(dv);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(db);
}
catch
{
//Failed
strVersion = "";
}
It works fine except that when the code finishes running it holds an internal MSI file handle so when I try to move or rename the MSI file I get the error that the file is still in use. This continues until I actually navigate away from the ASPX page that calls the method above.
My question is, I obviously didn't close some handle or object in the code above. But what could that be?
PS. I'm testing it in a development IDE from VS2010.
EDIT: Edited the code like it should be after Adriano's suggestion. Thanks!
The COM object has not been released (it should be auto-released when it goes out of scope but in .NET this doesn't work really well). Because it does not implement the IDisposable interface you can't call its Dispose() method and you can't use it inside an using statement. You have to explicitly call Marshal.FinalReleaseComObject. For example:
try
{
// Your stuffs
}
finally
{
dv.Close();
Marshal.FinalReleaseComObject(dv);
Marshal.FinalReleaseComObject(db);
}
Moreover note that you do not really need a call to the Commit() method because you didn't make any change but just a query.
FWIW, you should be using Windows Installer XML (WiX) Deployment Tools Foundation (DTF). It's an FOSS project from Microsoft that can be found on CodePlex. It has MSI interop libraries with classes that are very similar to the COM classes but implement IDisosable and use P/Invoke instead of COM behind the scenes. There is even support for Linq to MSI if you want. And the full source code is available.
DTF is the gold standard for MSI interop in a .NET world. Here are two examples:
using System;
using System.Linq;
using Microsoft.Deployment.WindowsInstaller;
using Microsoft.Deployment.WindowsInstaller.Linq;
namespace ConsoleApplication3
{
class Program
{
const string DATABASE_PATH = #"C:\FOO..MSI";
const string SQL_SELECT_PRODUCTVERSION = "SELECT `Value` FROM `Property` WHERE `Property`='ProductVersion'";
static void Main(string[] args)
{
using (Database database = new Database(DATABASE_PATH, DatabaseOpenMode.ReadOnly))
{
Console.WriteLine(database.ExecuteScalar(SQL_SELECT_PRODUCTVERSION).ToString());
}
using (QDatabase database = new QDatabase(DATABASE_PATH, DatabaseOpenMode.ReadOnly))
{
var results = from property in database.Properties where property.Property == "ProductVersion" select property.Value;
Console.WriteLine(results.AsEnumerable<string>().First());
}
}
}
}
try to Dispose the Objects.
dv.Dispose();
db.Dispose();