2

I have C# Code where I am invoking SAP BAPI, but sometime it takes too long to get a response back.

I can only wait for 3 seconds to get a response back. If it's does not return in 3 seconds, then I would like to terminate the call and continue with the next line.

funcArtike2.SetValue("CLI", CLI);             
funcArtike2.Invoke(rfcDest);

string CA = funcArtike2["CONTRACT_ACCOUNT"].GetValue().ToString().Trim() != "".ToString() ? funcArtike2["CONTRACT_ACCOUNT"].GetValue().ToString().Trim() : "X";
//IRfcStructure RETURN = funcArtike2["RETURN"].GetStructure();
string BP = funcArtike2["BUSINESS_PARTNER"].ToString().Substring(funcArtike2["BUSINESS_PARTNER"].ToString().IndexOf("=")+1);

funcArtike2.Invoke(rfcDest); is the statement I want to skip after waiting for 3 seconds.

reduckted
  • 2,358
  • 3
  • 28
  • 37
BilalAhmed
  • 191
  • 12

2 Answers2

5

Try this:

AutoResetEvent signal = new AutoResetEvent(false);
Timer timer = new Timer(3000);
timer.Elapsed += (sender, e) => signal.Set();        

funcArtike2.SetValue("CLI", CLI);

Thread thread = new Thread(()=>{
            funcArtike2.Invoke(rfcDest);
            signal.Set();
        });

thread.Start(); //start the function thread
timer.Start(); //start the timer

signal.WaitOne(); //waits for either the timer to elapse or the task to complete

string CA = funcArtike2["CONTRACT_ACCOUNT"].GetValue().ToString().Trim() != "".ToString() ? funcArtike2["CONTRACT_ACCOUNT"].GetValue().ToString().Trim() : "X";
            //IRfcStructure RETURN = funcArtike2["RETURN"].GetStructure();
string BP = funcArtike2["BUSINESS_PARTNER"].ToString().Substring(funcArtike2["BUSINESS_PARTNER"].ToString().IndexOf("=")+1);

We assume that the call:

funcArtike2.Invoke(rfcDest);

is synchronous, otherwise it will not work.

Note also that this will not kill the funcArtike2.Invoke(rfcDest) method call, just ignore it and move on. So if you start any expensive operations (e.g. DB call, file, IO, heavy computation), bad luck since you need to take care of that yourself.

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
Tamas Ionut
  • 4,240
  • 5
  • 36
  • 59
-1
var response = expectedResponse;
var timer = System.Diagnostics.Stopwatch.StartNew();
while(timer.ElapsedMilliseconds < 3001)
{
     //Evaluate to see if you have received the response.
     if(response != null) { funcArtike2.Invoke(rfcDest); break; }
     if(timer.ElapsedMilliseconds == 3000) { throw new TimeoutException("Response was not received within three seconds."); 
}
// Handle the exception down here.

If you do not need the response to continue your work then remove the exception and have your code continue below the loop.

  • No the best solution since it will call, DoWork() a lot of times. – Tamas Ionut Mar 25 '16 at 14:41
  • This is just an illustration, the OP can manipulate it to fit his required business logic. For instance, DoWork() could check the input parameter for a null value and break if a response has been received. Use your imagination.;) – Daniel Curtis Mar 25 '16 at 14:44
  • It's a pretty bad illustration since it will wait in all cases 3 seconds, even if the function call will take less. – Tamas Ionut Mar 25 '16 at 14:45