我有Duplex和Sessionfull服务以及操作:
public FindStudies_DTO_OUT FindStudies(FindStudies_DTO_IN findStudies_DTO_IN)
{
var token = Token;
List<Study_C> ret = new List<Study_C>();
_dispatcherCallBack = OperationContext.Current.GetCallbackChannel<IDispatcherCallBack>();
AnnuncedFindStudies += DispatcherService_AnnuncedFindStudies;
AnnuncedSPError += DispatcherService_AnnuncedSPError;
Parallel.ForEach(Cluster, sp =>
{
//Blah blah
OnAnnuncedSPError(new SPError_DTO()
{
ServicePointName = sp.Name,
ErrorMessage = "Ping failed for " + sp.Name
});
var result = new List<Study_C>();//Filled
lock (ret)
{
OnAnnounceFindStudies(new FindStudies_DTO()
{
ServicePointName = sp.Name,
Studies = result
});
ret.AddRange(result);
}
//blah blah
});
return new FindStudies_DTO_OUT(ret.Sort(findStudies_DTO_IN.SortColumnName, findStudies_DTO_IN.SortOrderBy));
}
和消费者方面(通用处理程序中的Web应用程序):
var findTask = Task.Factory.StartNew(() =>
{
DispatcherClient dispatcherClient = new DispatcherClient(new DispatcherCallBack(), "dispatcherEndPoint", Token, Global.Cluster);
dispatcherClient.AnnuncedSPError += DispatcherClient_AnnuncedSPError;
dispatcherClient.AnnuncedFindStudies += DispatcherClient_AnnuncedFindStudies;
var res = dispatcherClient.FindStudies(new FindStudies_DTO_IN(startIndex, numberOfRows, col.FromText(sortColumnName), sort.FromText(sortOrder), criteria, searchMatching));
studies = Studies;
});
findTask .Wait();
在客户端,当我在var findTask
上设置断点时,一切都运行正常,但是当我删除断点时,它只是在第一次运行,但之后我得到了以下异常:
InvalidOperationException:此时无法启动异步操作。异步操作只能在异步处理程序或模块中启动,或者在页面生命周期中的某些事件中启动。如果在执行页面时发生此异常,请确保将页面标记为&lt;%@ Page Async =“true”%&gt;。此异常还可能表示尝试调用“异步void”方法,该方法通常在ASP.NET请求处理中不受支持。相反,异步方法应该返回一个Task,调用者应该等待它。
有人知道应该如何实施客户端吗?
提前致谢。
答案 0 :(得分:0)
我不知道为什么我不能在客户端使用无限wait
,但从我读过的here开始,建议不要这样做asyc过度同步,反之亦然。
无论如何,我已通过以下解决方案解决了这个问题:
在服务器端运行一个任务,并在其中处理一些事件:
public FindStudies_DTO_OUT FindStudies(FindStudies_DTO_IN findStudies_DTO_IN)
{
var token = Token;
List<Study_C> ret = new List<Study_C>();
_dispatcherCallBack = OperationContext.Current.GetCallbackChannel<IDispatcherCallBack>();
AnnuncedFindStudies += (s, e) =>
{
_dispatcherCallBack.OnAnnounceFindStudies(e);
};
AnnuncedSPError += (s, e) =>
{
_dispatcherCallBack.OnAnnunceSPError(e);
};
AnnuncedComplete += (s, e) =>
{
_dispatcherCallBack.OnAnnunceComplete();
};
Task.Run(() =>
{
//Blah blah
if (proxyGetError)
OnAnnuncedSPError(new SPError_DTO()
{
ServicePointName = sp.Name,
ErrorMessage = "Ping failed for " + sp.Name
});
var result = new List<Study_C>();//Filled
lock (ret)
{
OnAnnounceFindStudies(new FindStudies_DTO()
{
ServicePointName = sp.Name,
Studies = result
});
}
//blah blah
OnAnnounceComplete();
});
return new FindStudies_DTO_OUT();
}
在消费者方面,任务也会在超时时运行,并在AnnuncedComplete
被提升时完成:
DispatcherClient dispatcherClient = new DispatcherClient(new DispatcherCallBack(), "dispatcherEndPoint", Token, Global.Cluster);
Task.Run(() =>
{
studies = new List<Study_C>();
try
{
ManualResetEvent ev = new ManualResetEvent(false);
dispatcherClient.AnnuncedSPError += (s, e) =>
{
spErrorMessage += e.ServicePointName + "<br/>";
};
dispatcherClient.AnnuncedFindStudies += (s, e) =>
{
lock (studies)
{
studies.AddRange(e.Studies);
}
};
dispatcherClient.AnnuncedComplete += (s, e) =>
{
ev.Set();
};
var rrr = dispatcherClient.FindStudies(new FindStudies_DTO_IN(startIndex, numberOfRows, col.FromText(sortColumnName), sort.FromText(sortOrder), criteria, searchMatching)).Studies;
ev.WaitOne();
}
catch (Exception exp)
{
Logging.Log(LoggingMode.Error, "Failed to Find Studies by Dispatcher, EXP:{0}", exp);
}
}).Wait(dispatcherClient.Endpoint.Binding.ReceiveTimeout);
主要问题是findTask.Wait()
,没有毫秒超时
但是通过设置任务的毫秒超时,一切都很好。
我认为在ASP.Net管道中一个无限的任务是不可接受的,因为引擎应该知道一个任务最终会被超时结束....