Category: .NET

Async + sync completion + lock

Let’s suppose that you have 2 functions = one true sync and one true async . Let’s suppose more that the sync one can must finish before calling next time ( think about some weird COM component or , in our days, SqlConnection )

If we look just at the async function , we could wait for all. However, the sync function must be called sync

One solution is to make different calls:


var list = new List<Task<int>>(nr);
//add async to list

await Task.WhenAll(list)

//call each sync



But I want to make really async – and one solution is lock

We could wrote the sync function in async manner like this:


//SemaphoreSlim sem = new SemaphoreSlim(1);
static object myObject = new object();
async Task<int> syncTask(int i)         {             
lock (myObject)             
//try{                 
//await sem.WaitAsync();                                 
CallSyncFunction();                             
//}             
//finally             
//{                 
//sem.Release();             
//}                                   
}

The trick that I  used is lock, because the syntax is easier than SemaphoreSlim (BTW: if you want to learn about threading, jump directly to http://www.albahari.com/threading/)
In this manner, the sync function is modified in async -and, more, it waits for completion before entering the second time.

The code is on github on

More details in the Wiki https://github.com/ignatandrei/AsyncSyncLock/wiki or in the code https://github.com/ignatandrei/AsyncSyncLock/

spot errors in VB

Please spot the errors in the following code in VB.NET:

Dim Diff As String = con.ExecuteCommand(“SELECT DATEDIFF(Day, (select [date] from table where Username = ‘” + txtUserName.Text + “‘), ‘” & DateTime.Now.ToString() & “‘)”)
If (Diff > 30) Then
Response.Redirect(“PleaseChangeMyPassword.aspx”)
End If

 

( find at least 3…)

Side note:

No wonder Visual Basic has died ( more or less). Guess future of server javascript ….

Generating Visual Studio solution( or project) references

A Visual Studio pacakge is a plugin of Visual Studio that can do (almost) anything inside Visual Studio

I have made a small project that generates a list of all solution ( or project) references from VS:

 

            foreach (var project in dte.Solution.Projects)
            {
                var p = project as Project;
                if (p == null)
                {
                    continue;
                }

                var vsproject = p.Object as VSLangProj.VSProject;
                if (vsproject == null)
                    continue;

                string nameProject = p.Name;
                foreach (var reference in vsproject.References)
                {
                    var r = reference as Reference;
                    if (r == null)
                        continue;

                    var pathRef = r.Path;

                    //this is a package                    
                    var pa = new PackageAdd();
                  
                    pa.ProjectName = p.Name;
                    pa.IdentifierPackage = r.Identity;
                    pa.VersionPackage = r.Version;
                    pa.NamePackage = r.Name;

                  



                    if (r.SourceProject != null)
                    {
                        
                        pa.NamePackage = r.SourceProject.Name;
                    }
                    sb.AppendLine(pa.ToString());
                }
            }

You can find the solution at https://github.com/ignatandrei/ToolsAndUtilities/tree/master/VS2015/FindReferencesVS

Also the video is at https://youtu.be/a3YHVjJ9fm4

Enjoy!

Thank you for all the API

In our days it is simpler to make an application by putting together some API . I wanted to make a list of all my 5 Minutes .NET playlist videos . First, I have tried to find an application(nothing). Then I have read  You Tube API from https://console.developers.google.com/apis/library . With 2 http requests( one for retrieving all videos from a playlist, the other to find video details) and a NuGet package to export to Excel/Word/PDF/HTML it was simple. You can find the whole project at https://github.com/ignatandrei/YouTube . A video demo at https://www.youtube.com/watch?v=wNHDsHtLBq4 . And the whole list at https://github.com/ignatandrei/ToolsAndUtilities/tree/gh-pages

IDisposable and Marshal.ReleaseCOMObject and dynamic in C#

 

If you have worked with COM, you know that for every COM object that you access is not only necessary to null the reference, but also call Marshall.ReleaseCOMObject .

This is a very error prone task, because you have all try / finally blocks

 
// declare a, ws, w 
try{ 
a=new Application(); 
ws = a.Workbooks; 
w = ws.Add(); 
//code 
}
 catch(...) {
 if( w != null){ 
Marshal.ReleaseComObject(w); 
w = null; 
}
 if(ws !=null){ 
Marshal.ReleaseComObject(ws); 
ws = null; 
} 
if( a!= null) { 
Marshal.ReleaseComObject(a); a= null; 
} 
} 

All of this could be done easy with IDisposable, if

1. IDisposable calls the Marshal.ReleaseCOMObject

2. Find a way to call methods / properties on the COM object from the class that implements IDisposable

 

I have done this and the result is like this:

 
using (dynamic a = new ComDisposable(new Application())) { 
using (dynamic ws = a.Workbooks) { 
using (dynamic w = ws.Add()) { 
using (var shs = w.Sheets) { 
using (var s = shs[1]) { 
//Worksheet a; 
using (var r = a.Range("A1")) { 
r.Value2 = "http://ignatandrei.github.io/ToolsAndUtilities/";; 
using (var f = r.Font) { 
f.Bold = true; 
}
 }
 }
 }
 w.SaveAs(fileName); 
w.Close(); 
} 
}
 a.Quit(); } 

 

Video at https://youtu.be/2qbAcSjL1gU

NuGet package at https://www.nuget.org/packages/ReleaseComObjectDisposable/

AppContext

AppContext is like Application in ASP.NET (MVC). You can see the value all over the application

AppContext.SetSwitch("OCR", true);

And we can have the result in all dll’s by

 public bool IsOCREnabled()
        {
            bool test;
            if (!AppContext.TryGetSwitch("OCR", out test))
                return false;

            return test;
        }

Video demo at https://youtu.be/GMgn4o3yPqw

Instrumentation in C# / .NET

For many programmers a try/catch with stack trace it is enough

try
{
var p = new Person();
p.DateOfBirth = DateTime.Now.AddYears(-10);
p.Drink(10, 2);
}
catch (Exception ex)
{
Console.WriteLine("ERROR OCCURED " + ex.StackTrace);
}

Others want to see also functions arguments, like in


p.Drink(10, 2);

will produce the result

ERROR An exception occured in method InstrumentationPostSharp.Person.Drink with (beersNumber = 10 , vodkaNumber = 2)

For this you can install the package
https://www.nuget.org/packages/LoggerAspect.Nlog

that have full source code at
https://github.com/vnvizitiu/AOP/tree/master/PostSharpTutorial

and watch my video for more details
https://youtu.be/qe2kpuuWXkw

RavenDB embedabble

I have made an application with RavenDB embeddable.

The good part is that is embeddable and easy to work with – at least, at start.

What I have learned:

  • If you forgot to use using, then RavenDB will throw an exception complaining about multiple sessions. Code:
 using (var session = instanceDefault.OpenSession(DatabaseName()))
{

//code
}

 

  • If you use multiple instance of the same EmbeddableDocumentStore , even on different default databases , then will complain about “temp path already used by another database instance “ . And the generics do NOT share the same instance of a static variable. And when you dispose a static singleton instance ? At the final of the application ( do not forget , otherwise you may have again “temp path already used by another database instance ” !)

 

  • The most simple index for new databases is RavenDocumentsByEntityName . Code:
//static EmbeddableDocumentStore instanceDefault;
var dbc = instanceDefault.DatabaseCommands.ForDatabase(DatabaseName());
                var defIndex = new RavenDocumentsByEntityName();
                
                defIndex.Execute(dbc,new DocumentConvention()
                {
                    DefaultUseOptimisticConcurrency = true                    
                    
                } );

 

  • If you create an index, create in the Database that needs. Otherwise if will complain when you get the data.  ( see previous code)

 

  • To manage data / databases , there is RavenDB Management Studio – a fancy name for an application that you can access ( by default ) at http://localhost:8080 . Code:
            instanceDefault = new EmbeddableDocumentStore();
//I have put this in app.config/web.config
            //instanceDefault.Configuration.Settings.Add("Raven/MaxSecondsForTaskToWaitForDatabaseToLoad", "60");
/*
<connectionStrings>
		<add name="RavenDB" connectionString="DataDir = ~\App_Data\Database"/>
	</connectionStrings>
   <appSettings>
	<add key="Raven/MaxSecondsForTaskToWaitForDatabaseToLoad" value="60"/>
*/
            instanceDefault.ConnectionStringName = "RavenDB";
            instanceDefault.Conventions.FindIdentityPropertyNameFromEntityName = (entity) => "ID";

            try
            {
                //To try in debug mode
                NonAdminHttp.EnsureCanListenToWhenInNonAdminContext(8080);
                instanceDefault.UseEmbeddedHttpServer = true;
                instanceDefault.Initialize();

            }
            catch (ReflectionTypeLoadException ex)
            {
                string message = "LoaderExceptions:";
                ex.LoaderExceptions.ForEach(it => message += it.Message + ";");
                throw new Exception(message, ex);
            }


 

( do not let this into Web Application if you want to deploy to a third party host)

 

  • Copy / paste database do not work. You must backup and restore data( preferably with RavenDB Management Studio )

 

  • RavenDB documentation is ok – however, embeddable database is not so represented very well

 

If you want to see a sample ( not very good, though) repository, I have created one at https://github.com/ignatandrei/RomaniaOpenData/blob/master/ROP/ROPInfrastructure/Repository.cs

Bottom line: I think that is good enough.

Export to Excel,Word , Pdf, Html,CSV

I have made an application / package that exports data ( classes/datatable/csv/json) to Word/Excel/PDF.

I have made several tries in the past , however now is the definitive source for .NET 4.x It is FULL code source, with tests and tutorials..

 

The code is at https://github.com/ignatandrei/Exporter 

The NuGet package is at https://www.nuget.org/packages/ExporterWordExcelPDF

The demo online is at http://exporter.azurewebsites.net/ 

The documentation is at https://github.com/ignatandrei/Exporter/wiki 

You can help with the project – please read https://github.com/ignatandrei/Exporter/wiki/Help-the-project 

So if you need Excel / Word / PDF to export, please consider this open source project.

Throw versus ThrowEx

 

 

When you intercept exceptions( for logging ) you can

 
catch (Exception ex)
            {
                //TODO: log : 
                //https://youtu.be/OvzcBTm3Sow
                string s = ex.Message;
                throw ex;
            }
 

or

 
catch (Exception ex)
            {
                //TODO: log : 
                //https://youtu.be/OvzcBTm3Sow
                string s = ex.Message;
                throw ;
            }

The difference is small – but the consequences are losing the original stack trace , if you

 throw ex; 

I have done a small video about this : https://youtu.be/Deigld3Bqko

I have not covered ExceptionDispatchInfo  that you can see an usage here: http://blogs.microsoft.co.il/sasha/2011/10/19/capture-transfer-and-rethrow-exceptions-with-exceptiondispatchinfo-net-45/

Andrei Ignat weekly software news(mostly .NET)

* indicates required

Please select all the ways you would like to hear from me:

You can unsubscribe at any time by clicking the link in the footer of our emails. For information about our privacy practices, please visit our website.

We use Mailchimp as our marketing platform. By clicking below to subscribe, you acknowledge that your information will be transferred to Mailchimp for processing. Learn more about Mailchimp's privacy practices here.