Multithreading Silverlight-限制应用程序一次只能调用一个WCF
Silverlight一次只能同时发送一定数量的WCF请求。我正在尝试序列化应用程序特定部分正在执行的请求,因为我不需要它们同时运行 问题如下(总结如下): “Silverlight应用程序中的WCF代理使用启动web服务调用的线程的SynchronizationContext来计划接收响应时异步事件处理程序的调用。当从Silverlight应用程序的UI线程启动web服务调用时,异步事件处理程序代码也将执行用户界面线程上的“e” 概要:基本上,如果阻止调用异步方法的线程,它将永远不会被调用 我无法找到正确的线程模型,这样可以以合理的方式满足我的需求 我唯一的另一个要求是我不希望UI线程阻塞 就我所见,如果UI线程有一个工作线程,它将调用作为Multithreading Silverlight-限制应用程序一次只能调用一个WCF,multithreading,silverlight,wcf,asynchronous,Multithreading,Silverlight,Wcf,Asynchronous,Silverlight一次只能同时发送一定数量的WCF请求。我正在尝试序列化应用程序特定部分正在执行的请求,因为我不需要它们同时运行 问题如下(总结如下): “Silverlight应用程序中的WCF代理使用启动web服务调用的线程的SynchronizationContext来计划接收响应时异步事件处理程序的调用。当从Silverlight应用程序的UI线程启动web服务调用时,异步事件处理程序代码也将执行用户界面线程上的“e” 概要:基本上,如果阻止调用异步方法的线程,它将永远不会被调用
操作
委托进行排队,然后使用自动resetEvent
在另一个工作线程中一次执行一个任务,那么应该工作。有两个问题:
1) 调用async的线程无法阻止,因为这样async就永远不会被调用。事实上,如果将该线程放入等待循环,我注意到它也不会被调用
2) 您需要一种方法从异步调用的已完成方法发出信号,表明它已完成
对不起,时间太长了,谢谢你的阅读。有什么想法吗?有一些选择: -您可以通过检查Agatha rrsl的实现或仅使用它而不是纯wcf来查看它。该框架允许您对请求进行排队。你可以读更多 -另一种选择是使用被动扩展。这里有一个SO示例和更多信息 -您可以尝试Jeffrey Richter提供的Power Thread库。他在他的书《CLR通过C#》中对此进行了描述。你可以找到图书馆。这会给你一些关于它的信息
-您可以随时滚动自己的实现。收益率报表在这里是一个很好的帮助。错误处理使解决方案变得非常困难。我使用了一个我自己构建的类来执行加载操作。使用该类,您可以注册不同域上下文的多个加载操作,然后逐个执行它们。当所有操作完成(成功或失败)时,您可以向被调用的类的构造函数提供一个操作 这是课程的代码。我认为它不完整,你必须改变它以符合你的期望。也许它能帮助你解决你的处境
public class DomainContextQueryLoader {
private List<LoadOperation> _failedOperations;
private Action<DomainContextQueryLoader> _completeAction;
private List<QueuedQuery> _pendingQueries = new List<QueuedQuery>();
public DomainContextQueryLoader(Action<DomainContextQueryLoader> completeAction) {
if (completeAction == null) {
throw new ArgumentNullException("completeAction", "completeAction is null.");
}
this._completeAction = completeAction;
}
/// <summary>
/// Expose the count of failed operations
/// </summary>
public int FailedOperationCount {
get {
if (_failedOperations == null) {
return 0;
}
return _failedOperations.Count;
}
}
/// <summary>
/// Expose an enumerator for all of the failed operations
/// </summary>
public IList<LoadOperation> FailedOperations {
get {
if (_failedOperations == null) {
_failedOperations = new List<LoadOperation>();
}
return _failedOperations;
}
}
public IEnumerable<QueuedQuery> QueuedQueries {
get {
return _pendingQueries;
}
}
public bool IsExecuting {
get;
private set;
}
public void EnqueueQuery<T>(DomainContext context, EntityQuery<T> query) where T : Entity {
if (IsExecuting) {
throw new InvalidOperationException("Query cannot be queued, cause execution of queries is in progress");
}
var loadBatch = new QueuedQuery() {
Callback = null,
Context = context,
Query = query,
LoadOption = LoadBehavior.KeepCurrent,
UserState = null
};
_pendingQueries.Add(loadBatch);
}
public void ExecuteQueries() {
if (IsExecuting) {
throw new InvalidOperationException("Executing of queries is in progress");
}
if (_pendingQueries.Count == 0) {
throw new InvalidOperationException("No queries are queued to execute");
}
IsExecuting = true;
var query = DequeueQuery();
ExecuteQuery(query);
}
private void ExecuteQuery(QueuedQuery query) {
System.Diagnostics.Debug.WriteLine("Load data {0}", query.Query.EntityType);
var loadOperation = query.Load();
loadOperation.Completed += new EventHandler(OnOperationCompleted);
}
private QueuedQuery DequeueQuery() {
var query = _pendingQueries[0];
_pendingQueries.RemoveAt(0);
return query;
}
private void OnOperationCompleted(object sender, EventArgs e) {
LoadOperation loadOperation = sender as LoadOperation;
loadOperation.Completed -= new EventHandler(OnOperationCompleted);
if (loadOperation.HasError) {
FailedOperations.Add(loadOperation);
}
if (_pendingQueries.Count > 0) {
var query = DequeueQuery();
ExecuteQuery(query);
}
else {
IsExecuting = false;
System.Diagnostics.Debug.WriteLine("All data loaded");
if (_completeAction != null) {
_completeAction(this);
_completeAction = null;
}
}
}
}
公共类DomainContextQueryLoader{
私有列表\u失败的操作;
私人行动(完成行动);;
私有列表_pendingQueries=新列表();
公共域ContextQueryLoader(操作完成操作){
if(completeAction==null){
抛出新ArgumentNullException(“completeAction”,“completeAction为null”);
}
这个._completeAction=completeAction;
}
///
///公开失败操作的计数
///
公共整数失败操作计数{
得到{
如果(_failedOperations==null){
返回0;
}
返回_failedOperations.Count;
}
}
///
///公开所有失败操作的枚举数
///
公共IList失败操作{
得到{
如果(_failedOperations==null){
_failedOperations=新列表();
}
返回失败的操作;
}
}
公共IEnumerable QueuedQuery{
得到{
返回待处理查询;
}
}
公共事业执行{
得到;
私人设置;
}
公共void排队查询(DomainContext上下文,EntityQuery查询),其中T:Entity{
如果(正在执行){
抛出新的InvalidOperationException(“查询无法排队,因为正在执行查询”);
}
var loadBatch=new QueuedQuery(){
Callback=null,
上下文=上下文,
Query=Query,
LoadOption=LoadBehavior.KeepCurrent,
UserState=null
};
_pendingQueries.Add(loadBatch);
}
public void ExecuteQueries(){
如果(正在执行){
抛出新的InvalidOperationException(“正在执行查询”);
}
如果(_pendingQueries.Count==0){
抛出新的InvalidOperationException(“没有排队执行的查询”);
}
IsExecuting=true;
var query=DequeueQuery();
执行(查询);
}
私有void ExecuteQuery(QueuedQuery){
System.Diagnostics.Debug.WriteLine(“加载数据{0}”,query.query.EntityType);
var loadOperation=query.Load();
loadOperation.Completed+=新事件处理程序(OnOperationCompleted);
}
private QueuedQuery DequeueQuery(){
var query=_pendingquerys[0];
_pendingQueries.RemoveAt(0);
返回查询;
}
私有void操作已完成(对象发送方,事件参数e){
LoadOperation LoadOperation=发送方作为LoadOperation;
loadOperation.Completed-=新事件处理程序(OnOperationCompleted);
if(loadOperation.HasError){
失败操作。添加(加载操作);
}
如果(_pendingQueries.Count>0){
var query=DequeueQuery();
执行(查询);
}
否则{
IsExecuting=false;
System.Diagnostics.Debug.WriteLine(“加载的所有数据”);
如果(_completeAction!=null){
_完成动作(本);
_completeAction=null;
}
}
}
}
更新:
我刚刚注意到你不是