cancel
Showing results for 
Search instead for 
Did you mean: 

SAPbobsCOM and C# multithreading

Former Member
0 Kudos

I'm writing a web application which updates objects in SAP BO. It works perfect except it's taking forever to setup the connection to SAP and update the objects. So I thought to create a background thread to handle the update to SAP while the active thread can continue processing the current request. But it appears not to be as easy as this. I'm no expert on writing multi threaded code but the few multi threaded methods I wrote work just fine.

This is what I try to do: on the website a user can change his phone number. The web app saves this 'change' in a database. Just after it is saved in the database a new thread is started. This background thread checks the database and pickes up all pending changes and tries to push them to SAP. The code works when don't try to run it in a background thread. When I run it in a background thread I can step through the code with the debugger until the line company.Connect(). This normaly takes a while before I can step to the following line in code, but instead it quits debugging. It looks like the thread is killed when a response is send back from SAP.

Does anyone managed to get a similar solution working and can push me in the right direction?

I know I can write for example a windows service which does just what the background thread is doing, but this means you have to install a windows service on the webserver. Thats what I trying to avoid for multiple reasons.

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

Just guessing here, but you could look into the 'apartment state' of the threads/application: MTA/STA and such.

Former Member
0 Kudos

Yes, I tried that. But I couldn't get it to work. Everytime the component returns from opening the connection to SAP the app crashes. Changing MTA en STA changes the way it crashes but it stil crashes.

Answers (2)

Answers (2)

Former Member
0 Kudos

I found the solution. Instead of creating a background thread to connect to SAP, I create a new application domain. The code connecting to SAP runs in this appdomain. I start this appdomain in a separate thread.

I haven't fully tested this yet, so any suggestions to optimize the code are greatly appriciated.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Web;
using System.IO;
using System.Reflection;



namespace SapSync {
    public class SapTasker {

        /// <summary>
        /// Sends all updates in the queue to SAP in a separate thread.
        /// </summary>
        public static void RunUpdate() {
            Thread thread = new Thread(RunUpdateInNewAppDomain);
            thread.Priority = ThreadPriority.BelowNormal;
            thread.Start();
        }

        private static void RunUpdateInNewAppDomain() {
            AppDomainSetup ads = new AppDomainSetup();
            ads.ApplicationBase = System.Environment.CurrentDirectory;
            ads.DisallowBindingRedirects = false;
            ads.DisallowCodeDownload = true;
            ads.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;

            AppDomain appd = AppDomain.CreateDomain("sapUpdate", null, ads);

            // Create an instance of MarshalbyRefType in the second AppDomain. 
            // A proxy to the object is returned.
            MarshalByRefType mbrt = (MarshalByRefType)appd.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(MarshalByRefType).FullName);

            // Call a method on the object via the proxy, passing the 
            // default AppDomain's friendly name in as a parameter.
            mbrt.UpdateSap();

            AppDomain.Unload(appd);
        }

    }

    // Because this class is derived from MarshalByRefObject, a proxy 
    // to a MarshalByRefType object can be returned across an AppDomain 
    // boundary.
    public class MarshalByRefType : MarshalByRefObject {
        //  Call this method via a proxy.
        public void UpdateSap() {
            SapUpdateHandler suh = new SapUpdateHandler();
            suh.UpdateSap();
        }
    }

    }

Former Member
0 Kudos

Hello

Yes, i have done several applications like this in the last 4 years.

Create a separate application as a windows service, which can track the changes and can push them in SAP.

To build up a windows service:

http://msdn.microsoft.com/en-us/magazine/cc301845.aspx

To do:

1, In your web applcation you will log the changes into a custom table / (or Xml File )

2 Create a separate windows service which monitors time by time (by a .NET timer) the custom table (or FileSystem for xml files) and looking for changes

When a change occurs, it will update B1 via DI API.

The windows service can connect to B1 at startup and should be restarted (1once a day) regulary (reason: DI API Garbage). This windows service performance can be very good.

Xml files can be stuctutred as SAP B1 BO Xml, and can be distributed between Web Server and SAP B1 server by ftp, filesystem, etc.

I hope i can push you into the right direction.

Regards

J.

Former Member
0 Kudos

The windows service is indeed a solution. But I don't want to use it when I don't need to for various reasons. It has to be maintained and it is not an option when the app needs to be deployed on a shared server.

Edited by: El Barto on Mar 29, 2010 11:17 AM