WCF-调用Web服务完成事件是在等待后执行
我调用了一个WCF,方法的完成事件是在等待方法之后调用的WCF-调用Web服务完成事件是在等待后执行,wcf,asynchronous,async-await,Wcf,Asynchronous,Async Await,我调用了一个WCF,方法的完成事件是在等待方法之后调用的 public void my_method() { Task task = Task.Run(async () => await DoWorkAsync()); task.Wait(); } public async Task DoWorkAsync() { await Task.Run(() =>
public void my_method()
{
Task task = Task.Run(async () => await DoWorkAsync());
task.Wait();
}
public async Task DoWorkAsync()
{
await Task.Run(() =>
{
wcf1.ServiceAnnonces s = new wcf1.ServiceAnnonces();
s.DoWorkCompleted += S_DoWorkCompleted;
s.DoWorkAsync();
});
}
private string retour;
public string Retour { get => retour; set => retour = value; }
private void S_DoWorkCompleted(object sender, wcf1.DoWorkCompletedEventArgs e)
{
Retour = e.Result;
}
我使用以下代码调用方法:
Droid.Resources.ISvAnnoncesSoap s = new Droid.Resources.ISvAnnoncesSoap();
s.ma_methode();
LbResulat.Text = s.Retour;
我的服务:
[ServiceContract]
public interface IServiceAnnonces
{
[OperationContract]
string DoWork();
}
public class ServiceAnnonces : IServiceAnnonces
{
public string DoWork()
{
return "coucou";
}
}
}
但在lbresult.Text=s.Retour之后抛出le Completed事件
谢谢你的帮助
编辑:
我删除了一些行代码。我现在的代码:
public void ma_methode()
{
wcf1.ServiceAnnonces s = new wcf1.ServiceAnnonces();
s.DoWorkCompleted += S_DoWorkCompleted;
s.DoWorkAsync();
}
private string retour;
public string Retour { get => retour; set => retour = value; }
private void S_DoWorkCompleted(object sender, wcf1.DoWorkCompletedEventArgs e)
{
Retour = e.Result;
}
并直接致电:
Droid.Resources.ISvAnnoncesSoap s = new Droid.Resources.ISvAnnoncesSoap();
s.ma_methode();
LbResulat.Text = s.Retour;
但相同,但完成的事件在lbresult.Text=s.Retour之后抛出;所以我的Retour是空的。假设DoWorkAsync()
和DoWorkCompleted
是为您的WCF服务合约生成的客户端代理,那么“问题”是您没有阻止/等待DoWorkCompleted
回调的完成-您正在调用DoWorkAsync()
然后您的代码继续。稍后,WCF调用完成并调用回调(这就是WCF中异步客户端方法代理对的工作方式-它们早于.Net 4.5的wait
)
您可以“重新同步”代码,例如,使用允许代码等待回调完成并发出任务已完成的信号:
public async Task DoWorkAsync()
{
var tcsWorkDone = new TaskCompletionSource<bool>();
wcf1.ServiceAnnonces s = new wcf1.ServiceAnnonces();
s.DoWorkCompleted += (sender, e) =>
{
S_DoWorkCompleted(sender, e);
tcsWorkDone.SetResult(true);
};
s.DoWorkAsync();
await tcsWorkDone.Task;
}
但是请注意,回调可以位于不同的线程上,因此您可能需要适当的(重新)调用代码来确保在UI线程上更新任何UI工件,如标签/文本框
Re:不使用任务。运行
比使用Task.Run更好的方法是
public async Task my_method()
{
return await DoWorkAsync();
}
或者,如果没有其他工作,只需返回任务供调用者等待:
public Task my_method()
{
return DoWorkAsync();
}
但是,如果您确实无法使my_方法异步,那么就不要使用任务启动第二个线程。运行然后在第一个线程上阻塞,然后您可以:
据猜测,s.DoWorkAsync()
也是异步的,应该等待。我很确定您不需要所有这些Task.Run的
——您能为ServiceAnnonces.doworksync()提供代码或方法签名吗代码>谢谢我编辑我的博文!非常感谢您的解释,我试着理解,并告诉您是否可以。我已经很久没有使用WCF了,但现在您似乎可以生成一个-这可能是处理代码的正确异步方式。
public Task my_method()
{
return DoWorkAsync();
}
public void my_method()
{
DoWorkAsync()
.GetAwaiter()
.GetResult();
}