[英]call asynchronous operation by task
I have Duplex and Sessionfull service and an operation as: 我有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));
}
and In consumer side (Web application in generic handler): 和在消费者方面(通用处理程序中的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();
in client-side when I set break-point on var findTask
everything works perfectly but when I remove break-point it works just in the first go but after that I have get the below exception: 在客户端,当我在var findTask
上设置断点时,一切工作正常,但是当我删除断点时,它只是在第一步中起作用,但是在此之后,我得到了以下异常:
InvalidOperationException: An asynchronous operation cannot be started at this time. InvalidOperationException:此时无法启动异步操作。 Asynchronous operations may only be started within an asynchronous handler or module or during certain events in the Page lifecycle. 异步操作只能在异步处理程序或模块内或在页面生命周期中的某些事件期间启动。 If this exception occurred while executing a Page, ensure that the Page is marked <%@ Page Async="true" %>. 如果在执行页面时发生此异常,请确保该页面被标记为<%@ Page Async =“ true”%>。 This exception may also indicate an attempt to call an "async void" method, which is generally unsupported within ASP.NET request processing. 此异常也可能表示尝试调用“异步无效”方法,ASP.NET请求处理通常不支持该方法。 Instead, the asynchronous method should return a Task, and the caller should await it. 而是,异步方法应返回一个Task,而调用者应等待它。
does anybody know how the client-side should be implemented? 有人知道应该如何实现客户端吗?
Thanks in advance. 提前致谢。
I don't know why I can't use infinite wait
in client side, but from what I have read here it is recommended don't do that asyc over sync and vice versa. 我不知道为什么我不能在客户端使用无限wait
,但是根据我在这里所读的内容,建议不要在同步中使用asyc,反之亦然。
Anyway I have resolved this problem by below solution: 无论如何,我已经通过以下解决方案解决了这个问题:
In server side a task be run and some event are handled in that: 在服务器端运行一个任务,并在其中处理一些事件:
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();
}
and in consumer side a task be run also with a timeout and it be completed when AnnuncedComplete
get raised: 在使用者方面,任务也会超时运行,并在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);
The main problem was findTask.Wait()
with no milliseconds timeout but by setting milliseconds timeout for task everything works nice. 主要问题是findTask.Wait()
没有毫秒超时,但是通过为任务设置毫秒超时,一切正常。
I think in ASP.Net pipeline an infinite task is not acceptable for this reason engine should know a task will be ended finally by timeout.... 我认为在ASP.Net管道中,无限任务是不可接受的,因为这个原因,引擎应该知道任务最终将因超时而结束。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.