WebService如何不等到任务完成

时间:2015-03-22 18:46:53

标签: c# wcf async-await

我在WebService中有一个c#函数来保存正在修改或添加的记录。

public bool UpdateEmployeeInfo(DataSet ds, int userId) {

    bool returnVal = true;
    Guid employeeUid = Guid.Empty;


    SqlConnection conn = new SqlConnection(InfoTacto.Framework.WebServices.Common.GetConnectionString());
    conn.Open();
    SqlTransaction trans = conn.BeginTransaction(IsolationLevel.ReadUncommitted, "UpdateEmployeeInfo");

    try {
        if (ds != null && ds.Tables.Contains("employee") && ds.Tables["employee"].Rows.Count > 0) {
            DataRow mainRow = ds.Tables["employee"].Rows[0];
            employeeUid = new Guid(mainRow["employeeUid"].ToString());
        }

        // depending on the tables being modified, _sendMessage can be true or false
        _sendMessage = EmployeeUpdate.UpdateEmployeeMethods(ds, trans, userId);

        trans.Commit();

    } catch (Exception err) {

        trans.Rollback();

        returnVal = false;

    } finally {
        //if(conn.State == ConnectionState.Open) 
        conn.Close();
    }

    // send push message for real time sync

    if (_sendMessage) {
        // this service sometimes take between 1 to 5 seconds so I dont want to wait
        // until it has finished...
        Utility.MessageService sqs = new MessageService();
        sqs.SendMessage("employeeUid=" + employeeUid);
    }

    return returnVal;
}

所有表格成功更新后我检查我的webservice需要发送一条消息(到其他系统),这个动作有时需要几毫秒或最多5秒但我不希望我的桌面应用程序冻结等待我的webservice函数完成。

// this service sometimes take between 1 to 5 seconds so I dont want to wait
// until it has finished...
Utility.MessageService sqs = new MessageService();
sqs.SendMessage("employeeUid=" + employeeUid);
  

有关如何让服务器完成SendMessage功能的任何线索,以便我的UpdateEmployeeInfo不会等待它完成以便将returnVal值返回到我的客户端应用程序。

由于

3 个答案:

答案 0 :(得分:1)

你试过了吗?

Task t = Task.Run(()=>
{
    Utility.MessageService sqs = new MessageService();
    sqs.SendMessage("employeeUid=" + employeeUid);
});

答案 1 :(得分:1)

您应该考虑不直接将消息发送到其他系统,无论您是否在其他线程上执行此操作。而是使用队列解耦系统。将消息推送到队列并退出,然后让另一个系统从队列中读取。

有许多排队基础架构需要考虑,包括MSMQ,Azure存储队列,Azure服务总线队列,RabbitMQ等等。

答案 2 :(得分:0)

如果使用最新的WCF svcutil(版本4.5.1)为Utility.MessageService生成客户端,它实际上将为您生成方法调用的异步版本。然后,您可以拨打sqs.SendMessageAsync(),在发送邮件后不会等待。

这是一个示例服务接口:

[ServiceContract]
public interface IEmailService
{
    [OperationContract]
    void SendEmail(EmailDTO email);
}

使用4.5.1版本的svc util,这里是生成的客户端的摘录。请注意,AsyncSendEmail()SendEmailAsync()

public partial class EmailServiceClient : System.ServiceModel.ClientBase<IEmailService>, IEmailService
{

    . . .<SNIP> . . .

    public void SendEmail(EmailDTO email)
    {
        base.Channel.SendEmail(email);
    }

    public System.Threading.Tasks.Task SendEmailAsync(EmailDTO email)
    {
        return base.Channel.SendEmailAsync(email);
    }
}

对我来说,最新版本的svcutil位于C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\svcutil。此版本生成了我的服务方法的随附Async版本。早期版本的svcutil也在我的计算机上,未生成Async versions