jutrec

How to use SDK asynchronously

0 votes
Hi, I've been trying to send multiple packages asynchonously. After some testing, I discovered that it cannot truly run in parallel because EslClient.CreatePackage(DocumentPackage) acts as a bottleneck for my application. I figured that it must use some kind of lock mechanism to allow only one call at a time. So here are my questions.
  1. Why is there a lock in the CreatePackage function?
  2. Is there a way to work around it using the .Net SDK?
  3. If not, is there a way to do it with the REST API?
Thank you.

Approved Answer

Reply to: How to use SDK asynchronously

1 votes
Hi jutrec,
While it is true that you can call as many times as you want the method, it wont actually start processing until the previous one is over.
That statement is not true, since if each task was waiting on each other to complete, your document packages would be created in an orderly fashion (e.g. package 0, package 1, package 2, etc.). This is not the case. You can login to your sandbox and verify this. Although they start one after the other, they don't wait on each other to complete. Each CreatePackage() is running from a different EslClient, so at that point, it is out of the hands of the SDK what happens with the thread. https://msdn.microsoft.com/en-us/library/dd537609(v=vs.110).aspx You would be right in assuming that there would some queuing going, if I were using one EslClient. Again that is not the case. Also, on a side note, the SDK is available on our GitHub and is open-source. You can download it make changes that fits your needs. Or, as you suggested, you can use the REST API. Hope this helps. https://github.com/eSignLive/esl.sdk.net
Haris Haidary OneSpan Technical Consultant

Reply to: How to use SDK asynchronously

0 votes
How many packages are you looking to create asynchronously? To my knowledge, there is not limit on how many calls you can make to eSignLive's API at the same time. In my example, I had no problem creating 10 packages concurrently:
        public static void main()
        {
            Thread.CurrentThread.Name = "Main";

            Task[] taskArray = new Task[10];

            for (int i = 0; i  CreatePackage(temp));
            }
            Task.WaitAll(taskArray);
        }

        public static void CreatePackage(int index)
        {
            DocumentPackage package = PackageBuilder.NewPackageNamed("package " + index)
                .WithSigner(SignerBuilder.NewSignerWithEmail("[email protected]")
                    .WithFirstName("John")
                    .WithLastName("Smith")
                    .WithCustomId("Signer1"))
                .WithDocument(DocumentBuilder.NewDocumentNamed("something")
                    .FromFile("C:/Users/hhaidary/Desktop/PDFs/doc1.pdf")
                    .WithSignature(SignatureBuilder.SignatureFor("[email protected]")
                        .AtPosition(100, 100)
                        .OnPage(0)))
                .Build();

            PackageId packageId = new EslClient(Properties.Settings.Default.key, Properties.Settings.Default.url).CreatePackage(package);

            Debug.WriteLine(packageId.ToString());
        }
Haris Haidary OneSpan Technical Consultant

Reply to: How to use SDK asynchronously

0 votes
While it is true that you can call as many times as you want the method, it wont actually start processing until the previous one is over. I decided to decompile the dll to see what was up behind the curtain. The function EslClient.CreatePackage(DocumentPackage) calls EslClient.UploadDocument() which calls PackageService.UploadDocument. Here is the code for the latter
internal Silanis.ESL.SDK.Document UploadDocument(DocumentPackage package, string fileName, byte[] fileBytes, Silanis.ESL.SDK.Document document)
    {
      lock (PackageService.syncLock)
      {
        string local_0 = this.template.UrlFor(UrlTemplate.DOCUMENT_PATH).Replace("{packageId}", package.Id.Id).Build();
        Package local_1 = new DocumentPackageConverter(package).ToAPIPackage();
        Silanis.ESL.API.Document local_2 = new DocumentConverter(document).ToAPIDocument(local_1);
        try
        {
          string local_3 = JsonConvert.SerializeObject((object) local_2, this.settings);
          byte[] local_4 = Converter.ToBytes(local_3);
          string local_5 = this.GenerateBoundary();
          byte[] local_6 = this.CreateMultipartContent(fileName, fileBytes, local_4, local_5);
          return new DocumentConverter(JsonConvert.DeserializeObject(this.restClient.PostMultipartFile(local_0, local_6, local_5, local_3)), local_1).ToSDKDocument();
        }
        catch (EslServerException exception_0)
        {
          throw new EslServerException("Could not upload document to package. Exception: " + exception_0.Message, exception_0.ServerError, exception_0);
        }
        catch (Exception exception_1)
        {
          throw new EslException("Could not upload document to package. Exception: " + exception_1.Message, exception_1);
        }
      }
    }
Is there a way around the lock with the SDK or do I need to use the REST API?

Reply to: How to use SDK asynchronously

1 votes
I would also like to add that if you find anything that could potentially be a bottleneck or something that could be improved in terms of performance, I would love hear about it so I can forward it to our product management team :)
Haris Haidary OneSpan Technical Consultant

Hello! Looks like you're enjoying the discussion, but haven't signed up for an account.

When you create an account, we remember exactly what you've read, so you always come right back where you left off