none
Manual tasks vs asynchronous proxy calls RRS feed

  • Question

  • Suppose I have a service that has a function "int DoIt(SomeLargeObjectType)" (the significance of the type SomeLargeObjectType will become apparent later).

    In the client code I have a proxy that I can call the service on called "TheService". Are the two ways of calling the function equivalent:

    	SomeLargeObjectType MyObject = new SomeLargeObjectType() ;
    
    
    	// Method 1: using manual creation of a task...
    	Task<int> MyTask1 = Task.Run (() => return TheService.DoIt(MyObject) ) ;
    
    
    	// Method 2: using asynchronous WCF call...
    	Task<int> MyTask2 = TheService.DoItAsync(MyObject) ;
    

    I am not sure, but I think that there may be a subtle but important difference. Suppose now that immediately after the lines that call DoIt I add lines that modify the content of MyObject as follows:

    	SomeLargeObjectType MyObject = new SomeLargeObjectType() ;
    
    
    	// Method 1: using manual creation of a task...
    	Task<int> MyTask1 = Task.Run (() => return TheService.DoIt(MyObject) ) ;
    	ModifyTheObject( MyObject ) ;
    
    
    	// Method 2: using asynchronous WCF call...
    	Task<int> MyTask2 = TheService.DoItAsync(MyObject) ;
    	ModifyTheObject( MyObject ) ;
    
    

    I believe that with method 1 there is the possibility that ModifyTheObject could run before MyObject is sent off in the call to DoIt, so what appears at the service is a modified (or worse part modified) version of MyObject. Is that correct?

    I do not if method 2 is better. In this case is MyObject packaged up for sending before ModifyTheObject is called, and so is safer? Or is it open to the same problem that I think could exist in method 1.

    Thanks in advance for your insights.

    Andrew.


    • Edited by Andrew Ch. _ Tuesday, October 9, 2018 11:41 AM Added "Async" to the second methods.
    Tuesday, October 9, 2018 11:40 AM

All replies

  • Experimentation seems to imply that the DoItAsync approach suffers from the same problem; i.e. it returns before the MyObject has been packaged up to send to the service. Not the answer I was looking for.

    Does anyone know of an approach that guarantees that the original value gets sent to the service and not the modified value?

    Tuesday, October 9, 2018 3:10 PM
  • Hi Andrew,

    I quite agree with you . the Parameters will be sent after modification.
    I recommend you use the continuewith() method to make sure the tasks are executed sequentially. But there's one thing to note. The client generates the Async method without using Async/await keyword, and it also use the task class to complement the method (you could check it in the service reference).If the async/await keyword is used, the effect is consistent with the continuewith method.I have made a demo,wish it is useful to you.

    static void Main(string[] args)
            {
                int para1 = 5;
                //Task<int> task=Task.Run(()=> { return Do(para1); });
                //var result=task.ContinueWith((aa=> { Modify(ref para1); }));
                //Modify(ref para1);
                //Console.WriteLine(task.Result);
    
                Task<int> r = ProcessAsync(para1);
                Modify(ref para1);
                Console.WriteLine(r.Result);
                Console.ReadLine();
            }
            public static int Do(int result)
            {
                Thread.Sleep(3000);
                return result * 2;
            }
            public static async Task<int> ProcessAsync(int result)
            {
                Thread.Sleep(3000);
                return await Task.Run(()=>
                {
                    return result * 2;
                });
            }
            public static void Modify(ref int result)
            {
                result += 1;
            }
    

    Feel free to contact me if you have any questions.

    Best Regards
    Abraham

    Tuesday, October 16, 2018 5:00 PM
    Moderator