Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WebService如何不等待任务完成_C#_Wcf_Async Await - Fatal编程技术网

C# WebService如何不等待任务完成

C# WebService如何不等待任务完成,c#,wcf,async-await,C#,Wcf,Async Await,我在Web服务中有一个c#函数,用于保存正在修改或添加的记录 public bool UpdateEmployeeInfo(DataSet ds, int userId) { bool returnVal = true; Guid employeeUid = Guid.Empty; SqlConnection conn = new SqlConnection(InfoTacto.Framework.WebServices.Common.GetConnectionSt

我在Web服务中有一个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;
}
成功更新所有表后,我检查Web服务是否需要发送消息(到其他系统),此操作有时需要毫秒或最多5秒,但我不希望我的桌面应用程序冻结,等待我的Web服务功能完成

// 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
值返回到客户端应用程序


谢谢

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

下面是一个示例服务接口:

[ServiceContract]
public interface IEmailService
{
    [OperationContract]
    void SendEmail(EmailDTO email);
}
使用svc util的4.5.1版本,这里是从生成的客户端摘录的内容。请注意,
sendmail()
sendmailasync()
,有一个
Async
版本:

公共部分类EmailServiceClient:System.ServiceModel.ClientBase,IEmailService
{
. . . . . .
public void sendmail(EmailDTO电子邮件)
{
base.Channel.sendmail(email);
}
public System.Threading.Tasks.Task sendmailasync(EmailDTO电子邮件)
{
返回base.Channel.sendmailasync(电子邮件);
}
}
对我来说,svcutil的最新版本在
C:\ProgramFiles(x86)\Microsoft SDK\Windows\v8.1A\bin\NETFX 4.5.1 Tools\svcutil
中。此版本生成了我的服务方法的附带
Async
版本。同样在我的机器上的早期版本的
svcuti
,没有生成
异步版本

您是否尝试过:

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

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


有很多排队基础设施需要考虑,包括MSMQ、Azure存储队列、Azure服务总线队列、RabByMQ等等。创建另一个线程并执行您的任务,并使您的主线程可用于其他任务我可以如何做到这一点的任何示例?除此之外-在这里使用
SqlTransaction
没有多少好处,因为已经存在隐式事务,除了您正在更改为
ReadUncommitted
——这可能不是一个好主意,除非您真的想要脏读。而且,我们看不到一个
using
语句,这意味着您将泄漏资源。而且,即使事务失败,您也可能正在发送消息。@那么SqlTransaction没有处理我的代码?我不知道哪笔交易已经到位。我没有说它不起作用。只是它可能没有必要。同样,这取决于
UpdateEmployeeMethods
在做什么。很难从你的样品中分辨出来。如果它只是执行一个
SqlCommand
,那么它就没有必要了。SendMessage不是WCF服务,UpdateEmployeeInfo会,所以我想我必须创建一个与Khurram Ali评论的主任务无关的任务,但不知道如何创建:)抱歉,我假设是WCF,因为WCF标记。UpdateEmployeeInfo会,但是另一个SendMessage只是一个简单的类。使用代码或Task.Factory.StartNew(()=>{})之间有什么不同吗;StartNew是危险的。你看,仅仅是启动这个任务并忘记它也是危险的。除非您在某处等待结果,否则可能会在任务完成之前终止任务。另请看我使用AmazonSQS,但如果Amazon响应延迟,我不想挂起我的主要方法。这在你的问题中并不明显。但不管怎样,我很惊讶你会被耽搁这么久。您的队列和应用程序是否位于附近?如果不是,考虑先写入本地队列,然后有一个单独的进程推送到主队列。(这种技术通常用于“偶尔连接”的客户端应用程序。)我想单独的进程将是一个很好的解决方案。好办法
Task t = Task.Run(()=>
{
    Utility.MessageService sqs = new MessageService();
    sqs.SendMessage("employeeUid=" + employeeUid);
});