C# using statement and the K2 APIs

Recently in one of our projects, we had to do some performance optimizations that required us to look a bit closer at the resources our application used. In general, you should always dispose an object that’s implementing the IDisposable interface.

K2’s client API’s use a connection to the K2 server which needs to be closed and disposed after you’re done using them. In C# you can use the using-statement to dispose your objects when you’re done with it. The using-statement only works on objects that inherits from IDisposable.
Here are some examples of how to correctly use the using-statement when using K2 API’s.

SourceCode.Workflow.Client

The namespace you use for all the client functionality. Getting the worklist, opening a worklistitem and actioning an action on a worklistitem is all done with this namespace. You use the SourceCode.Workflow.Client.Connection class to get a connection. With a using statement, it looks like this:

1
2
3
4
5
using (Connection con = new Connection())
{
        con.Open("localhost");
        Worklist wl = con.OpenWorklist();
}

You don’t have to Close() the connection because the Dispose() calls that automatically.

SouceCode.Hosting.Client.BaseAPI.BaseAPIConnection

All the other K2 API’s use a BaseAPIConnection. Basically every hosted service that the K2 server provides (except from the SourceCode.Workflow.Client stuff) inherits from BaseAPI which uses this connection type. Most of you will know this one from SourceCode.Workflow.Management. When building such a connection, the SCConnectionStringBuilder is easy to use.

The BaseAPI object has a CreateConnection() method which returns a BaseAPIConnection object – which is also a member variable in the class itself. That BaseAPIConnection has the IDisposable interface.

In the example below, we use the WorkflowManagementServer. Because that object does not have the IDisposable interface, but the BaseAPIConnection returned by the CreateConnection does, our code looks like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
SCConnectionStringBuilder conBuilder = new SCConnectionStringBuilder();
conBuilder.IsPrimaryLogin = true;
conBuilder.Integrated = true;
conBuilder.Host = "localhost";
conBuilder.Port = 5555;

WorkflowManagementServer wfmServer = new WorkflowManagementServer();
using (BaseAPIConnection con = wfmServer.CreateConnection())
{
	con.Open(conBuilder.ConnectionString);
	
	// do something with the API
	Roles roles = wfmServer.GetRoles(string.Empty); 
}

Again, no Close() is needed as the Dispose() calls that for you.

Again, no Close() is needed as the Dispose() calls that for you.
For those who noticed it, the connection object is also stored in the WorkflowManagementServer. So we can make our code a little bit clearer by doing it like this:

1
2
3
4
5
6
7
8
WorkflowManagementServer wfmServer = new WorkflowManagementServer();
using (wfmServer.CreateConnection())
{
	wfmServer.Open(conBuilder.ConnectionString);
	
	// do something with the API
	Roles roles = wfmServer.GetRoles(string.Empty); 
}

That’s it. Easy using-statements for your K2 code that cleans up you’re connection right.