Silverlight一次只能同时发送一定数量的WCF请求。我正在尝试序列化我的应用程序的特定部分正在执行的请求,因为我不需要它们同时运行。
问题如下(摘要如下): “Silverlight应用程序中的WCF代理使用启动Web服务调用的线程的SynchronizationContext来调度接收响应时异步事件处理程序的调用。当从Silverlight应用程序的UI线程启动Web服务调用时,异步事件处理程序代码也将在UI线程上执行。“ http://tomasz.janczuk.org/2009/08/improving-performance-of-concurrent-wcf.html
总结:基本上,如果你阻塞调用异步方法的线程,它将永远不会被调用。
我无法弄清楚正确的线程模型,这会以合理的方式给我我想要的东西。
我唯一的另一个要求就是我不希望UI线程被阻止。
据我所知,应的工作原理是,如果UI线程有一个工作线程,将调用排队为Action
个委托,则使用AutoResetEvent
在另一个工作线程中一次执行一个任务。有两个问题:
1)调用异步的线程无法阻塞,因为异步永远不会被调用。实际上,如果你把那个线程放到一个等待循环中,我就注意到它也没有被调用
2)您需要一种方法来从已完成的异步调用方法发出信号。
很抱歉这太久了,谢谢你的阅读。有什么想法吗?
答案 0 :(得分:1)
我使用了一个我自己构建的类来执行同步的加载操作。使用该类,您可以注册不同的domaincontexts的多个加载操作,然后逐个执行它们。当所有操作完成(成功或失败)时,您可以向被调用的类的构造函数提供Action。
这是该类的代码。我认为这不完整,你必须改变它以符合你的期望。也许它可以在你的情况下帮助你。
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;
}
}
}
}
<强>更新强> 我刚刚注意到你没有使用WCF RIA服务,所以也许这个课程对你没用。
答案 1 :(得分:0)