简体   繁体   English

通过任务调用异步操作

[英]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.

相关问题 具有异步IO操作的任务 - Task that has asynchronous IO operation 使用任务 <List<Task> &gt;用于C#中的异步递归操作 - Using Task<List<Task>> for asynchronous recursive operation in C# 在异步 MongoDb 调用中检查存储操作的状态 - Checking status of storage operation in asynchronous MongoDb call 从异步任务在主线程上调用委托 - Call delegate on main thread from asynchronous task Task.Result等待而不是继续异步操作 - Task.Result waits instead of continue asynchronous operation 任务“尚未计算”:异步模块或处理程序在异步操作仍处于挂起状态时完成 - Task “not yet computed”: An asynchronous module or handler completed while an asynchronous operation was still pending 在异步操作之后立即调用 Task.Wait() 是否等同于同步运行相同的操作? - Is calling Task.Wait() immediately after an asynchronous operation equivalent to running the same operation synchronously? 无法使用Windows Phone后台任务进行异步调用 - Unable to make asynchronous call using Windows Phone Background Task 在对 Post 方法的第二次调用中获得“异步模块或处理程序已完成,而异步操作仍处于挂起状态” - in the second call to Post method getting “An asynchronous module or handler completed while an asynchronous operation was still pending” 异步操作中的异步操作 - Asynchronous operations within an asynchronous operation
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM