javaweb如何实现服务端异步执行 100

现在需求是这样的,需要上传一个文件,然后服务端根据这个文件的内容作一些处理,然后导入到数据库,同时将处理后的文件生成一个新的文件提供下载,因为处理的时间比较长,所以想在后... 现在需求是这样的,需要上传一个文件,然后服务端根据这个文件的内容作一些处理,然后导入到数据库,同时将处理后的文件生成一个新的文件提供下载,因为处理的时间比较长,所以想在后台收到文件后生成一个任务号返回前台,然后服务端在后端进行处理,前端拿到这个任务号后可以后续通过任务号来查询并下载生成的心文件
多线程这部分学的不太好,知道大概思路是要新开一个线程去做,不过不知道具体该怎么做,希望能够提供一个简单的示例代码,主要就是怎样新开一个线程去做文件处理同时给前台返回一个任务号的,文件上传以及下载的部分已经写好,希望有大神能够帮忙,谢谢!
展开
 我来答
若以下回答无法解决问题,邀请你更新回答
司马刀剑
高粉答主

2018-10-17 · 每个回答都超有意思的
知道顶级答主
回答量:4.6万
采纳率:93%
帮助的人:7521万
展开全部
异步调用webseviced的方法如下:
通常的WEB服务中对WEB方法的调用都是在客户端发出请求后将一直等待,直到得到返回的结果为止,这样如果某些WEB方法的处理需要很长一段时间才能处理完成的话,将会大大降低程序的效率。但是如果采用异步调用的方式将能使这个问题得到有效的解决,让客户端在发出请求之后的等待时间里去做其他的事情而不是一直在那里呆呆在等待。
对异步调用的理解:
说白了异步调用其实就是调用者线程和执行被调用过程的线程并行执行。
实现WEB服务方法异步调用有四种方法可以实现
第一种方法:使用回调
使用这种方式来进行WEB服务方法的异步调用关键是在启动异步调用时传入一个代理实例作为调用结束时的回调方法。这样用以回调的方法调用结束异步调用的方法获得异步调用的结果。若调用方要跟异步调用同步,则需要在启动异步调用时传入一个同步对象[作为最后一个参数],然后在回调方法中通过IAsyncResult的AsyncState成员获得该对象。
举一个例子:
假如有下面一个WEB服务方法
[webmethod]
public string GetName(string name)
{return name;}
/*****************客户端调用**************************
class Client
{
localhost1.Serivice service=new localhost1.Service();
public void GetResults(IAsyncResult ar)
{
MannualResetEvent ent;
ent=(MannualResetEvent)ar.AsyncState;
string ret=service.EndGetName(ar);
Console.WriteLine("the result is:"+ret);
ent.Set();
}
public void CallWithBack()
{
string name="kim";
AsyncCallBack callBack;
callBack=new AsyncCallBack(GetResults);
MannualResetEvent ent=MannualResetEvent(false);
service.BeginGetName(name,callBack,ent);
//做其他的事情
ent.WaitOne();
}
static void Main(string[] ars)
{
CallWithBack();
}
}
第二种方法:使用轮询
轮询就是不断检查异步调用启动后获得的IasyncResult变量的IsCompleted属性,以等待异步调用结束。而一般在判断异步调用还未结束时,调用Thread类的静态方法Sleep(0)迫使当前线程由运行状态转入就绪状态。
如:
WEB服务方法还是以上面的例子为例:
客户端实现:
Class Client
{
localhost1.Serivice service=new localhost1.Service();
public void CallWithQuery()
{
string name="kim";
IasyncResult ar;
ar=service.BeginGetName(name,null,null);
while(!ar.IsCompleted)
{
//做其他事情
Console.WritleLine("Watting....");
Tread.Sleep(0);
}
string ret;
ret=service.EndGetName(ar);
Console.WriteLine("the result is:"+ret);
}
static void Main(string[] ars)
{
CallWithQuery();
}
}
第三种方法是:开始调用,结束调用
这种方式在启动异步调用后用结束异步调用的方式获取结果,如果异步调用没有结束,当前线成被阻塞。
如:
WEB服务方法还是以上面的例子为例:
客户端实现:
Class Client
{
localhost1.Serivice service=new localhost1.Service();
public void CallWithEnd()
{
string name="kim";
IasyncResult ar=service.BeginGetName(name,null,null);
string ret=service.EndGetName(ar);
Console.WriteLine("the result is:"+ret);
}
static void Main(string[] ars)
{
CallWithEnd();
}
}
最后一种方法是:开始调用,等待处理,结束调用
在我们启动异步调用后,客户获得了返回的IasyncResult成员,调用线成在IasyncResult 的AsyncWaitHandle属性表示的同步对象上等待,最后结束异步调用以获得结果。
如:
WEB服务方法还是以上面的例子为例:
客户端实现:
Class Client
{
localhost1.Serivice service=new localhost1.Service();
public void CallWithWaitEnd()
{
string name="kim";
IasyncResult ar=service.BeginGetName(name,null,null);
string ret;
//做其他事情
if(ar.AsyncWaitHandle.WaitOne(1000,false))
{
Console.WriteLine("Invoke over");
ret=service.EndGetName(ar);
}
else
{
Console.WriteLine("Continue watting...");
ret=service.EndGetName(ar);
Console.WriteLine("Invoke over");
}
Console.WriteLine("the result is:"+ret);
}
static void Main(string[] ars)
{
CallWithWaitEnd();
}
}
ps: 在产生的代理类中系统已经自动为我们创建了异步调用接口,不需要我们去再次实现。如Begin***,End***等。如上面的WEB方法GetName在代理类中的异步接口应该是下面这样:
public System.IasyncResult BeginGetName(string name,System.AsycnCallback callback,object asyncState)
public string EndGetName(System.IasyncResult reult)
对于其他的函数可以查阅MSDN
以上。
本回答被网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 1条折叠回答
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式