views:

48

answers:

2

I need to implement time calculation for repository methods in my asp .net mvc project classes. The problem is that i need to send time calculation data to WCF Service which is time consuming. I think about threads which can help to cal WCF service asynchronously. But I have very little experience with it. Do I need to create new thread each time or I can create a global thread, if so then how? I have something like that:

StopWatch class

public class StopWatch
{
    private DateTime _startTime;
    private DateTime _endTime;

    public void Start()
    {
        _startTime = DateTime.Now;
    }
    protected void StopTimerAndWriteStatistics()
    {
        _endTime = DateTime.Now;
        TimeSpan timeResult = _endTime - _startTime;
        //WCF proxy object
        var reporting = AppServerUtility.GetProxy<IReporting>();
        //Send data to server
        reporting.WriteStatistics(_startTime, _endTime, timeResult, "some information");
    }

    public void Stop()
    {
        //Here is the thread I have question with
        var thread = new Thread(StopTimerAndWriteStatistics);
        thread.Start();
    }
}

Using of StopWatch class in Repository

public class SomeRepository
{
    public List<ObjectInfo> List()
    {
        StopWatch sw = new StopWatch();
        sw.Start();
        //performing long time operation
        sw.Stop();
    }
}

What am I doing wrong with threads? How I can reuse thread for performance reason?

+1  A: 

Your code seems fine. Once you've finished the long running operation you are spawning a new thread and perform the call to the web service in this thread. This seems a good approach to me. Another possibility is to use the BeginXXX and EndXXX methods generated by the web service proxy (/async option of svcutil.exe).

Darin Dimitrov
I'm worrying about performance drawbacks with creating new thread each time. Maybe better to use global thread object for such operations?
Tim
There's no such thing as global thread object. Either create the thread manually (as you've done) or use BeginXXX, EndXXX methods which uses IO Completion ports and is very efficient because during the execution of the call no thread is being consumed. In this case the call to the web service starts from the main and this main thread is returned to the thread pool immediately.
Darin Dimitrov
Yes there is no global thread. But can we reuse thread somehow? Creating new thread each time is not very efficient
Tim
Yes, BeginXXX and EndXXX reuses threads from the thread pool. You could also do it manually: `ThreadPool.QueueUserWorkItem`.
Darin Dimitrov
Thank you for pointing me to proxy async methods. I will use this approach.
Tim
+1  A: 

Why not using the .NET ThreadPool, with the QueueUserWorkItem method? You won't have to worry about starting the thread, you just queue it and your done.

You'd just call something like

ThreadPool.QueueUserWorkItem(new WaitCallback(StopTimerAndWriteStatistics));

Or you could even use a lambda expression and get rid of the StopTimerAndWriteStatistics method. (Haven't tested this one)

ThreadPool.QueueUserWorkItem(() => {
    _endTime = DateTime.Now;
    TimeSpan timeResult = _endTime - _startTime;
    //WCF proxy object
    var reporting = AppServerUtility.GetProxy<IReporting>();
    //Send data to server
    reporting.WriteStatistics(_startTime, _endTime, timeResult, "some information");
                                    });
foliveira