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 等等。
我在 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 myUpdateEmployeeInfo
wont wait for it to complete in order to return myreturnVal
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 等等。