WebService如何不等到任务完成

WebService how to not wait until task is completed

我在 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;
}

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

// 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);

Any clue on how can I leave the server to complete that SendMessage function so my UpdateEmployeeInfo wont wait for it to complete in order to return my returnVal value to my client application.

谢谢

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

这是一个示例服务接口:

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

使用 4.5.1 版本的 svc util,这里是生成的客户端的摘录。请注意,SendEmail() 有一个 Async 版本,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.

你试过了吗:

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

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

有很多队列基础设施需要考虑,包括 MSMQ、Azure 存储队列、Azure 服务总线队列、RabbitMQ 等等。