0

I have the following function:

 private void SendSMSs(List<SMS> smsList)
    {
        foreach (var sms in smsList)
        {
           SendSMS smsSend = new SendSMS(sms.message, sms.number, 0, SmsResponseCallback);
            Console.WriteLine("Sent a SMS to " + sms.number);
        }
    }

    /// <summary>
    /// Call back for sending a sms
    /// </summary>
    public void SmsResponseCallback(FSK_SendSMS.FSK_SendSMS.SMS_Result result)
    {
        Console.WriteLine("Succesfully sent a SMS to " + result.Destination + " with result: " + result.Result);
    }

Now my issue is that each sms waits till it gets a response from the recipient.

I want to create a task for each sms that needs to be sent. So that they can all be sent asynchronously.

The function SendSMSs does need to wait for the tasks to Finnish. It must return as soon as it can, and the sms will then be sent in their own time?

So how can I create a task which will start straight away and then I can move on and create the next.

svick
  • 236,525
  • 50
  • 385
  • 514
Zapnologica
  • 22,170
  • 44
  • 158
  • 253

3 Answers3

0

You can do something like this using System.Threading;

private void SendSMSs(List<SMS> smsList)
{
    foreach(SMS sms in smsList)
    {
        Thread thread = new Thread(new ParameterizedThreadStart(SendOneSMS(sms)));
    }
}

private void SendOneSMS(SMS sms)
{
    SendSMS smsSend = new SendSMS(sms.message, sms.number, 0, SmsResponseCallback);
    Console.WriteLine("Sent a SMS to " + sms.number);
}

For doing the same job with Task using System.Threading.Tasks

foreach(SMS sms in smsList)
{
    var t = Task.Factory.StartNew(new Action(SendOneSMS(sms)));
}
Avishek
  • 1,896
  • 14
  • 33
0

If the function that sends the SMS does not have an async alternative, you could use the TPL to start a task that will eventually block a thread to send an SMS:

private Task SendSMSs(List<SMS> smsList)
{
    return Task.WhenAll(from sms in smsList select SendSMS(sms));
}

private Task SendSMS(SMS sms)
{
    return Task.Run(() =>
    {
        SendSMS smsSend = new SendSMS(sms.message, sms.number, 0, SmsResponseCallback);
        Console.WriteLine("Sent a SMS to " + sms.number);
    });
}
CMircea
  • 3,543
  • 2
  • 36
  • 58
0

If you do this with a TaskCompletionSourceyou will get a more scalable solution as Task.Run uses up a thread. I haven't compiled this but you should be able to do something like this:

private void SendSMSs(List<SMS> smsList)
{
    var messagesSent = smsList.Select (s => SendSMS(s) ).ToArray();
    Task.WaitAll(messagesSent);
}

private Task<SMS_Result> SendSMS(SMS sms)
{
    var tcs = new TaskCompletionSource<SMS_Result>();

    SendSMS smsSend = new SendSMS(sms.message, sms.number, 0, result =>
    {
        tcs.SetResult = result;
        Console.WriteLine("Succesfully sent a SMS to " + result.Destination + " with result: " + result.Result);
    }); 

    Console.WriteLine("Sent a SMS to " + sms.number);

    return tcs.Task;
}
NeddySpaghetti
  • 13,187
  • 5
  • 32
  • 61