里面asp.net V4环异步任务 [英] async task inside loop in asp.net v4
问题描述
我使用asp.net V4 C#和我的电子邮件地址列表。我希望我的管理员之一,可以键入消息,preSS发送,而对于电子邮件走出去一个接一个。
I am using asp.net v4 c# and I have a list of email addresses. I want one of my admins to be able to type a message, press "SEND" and for the emails to go out one by one.
我觉得最好的办法就是要利用.NET中的异步方法?发送按钮的OnClick的,我采取的电子邮件地址的列表,然后调用异步方法。我只是不知道如何接一个得到它遍历列表中的一个和断火的电子邮件。
The best way I think is to make use of the async methods in .net? OnClick of the send button, I take the list of email addresses then call the async method. I just don't know how to get it to loop through the list one by one and fire off the email.
时需要做一次,这样我可以节省针对用户的帐户发送的电子邮件的副本。
Is needs to be done one at a time so that I can save a copy of the email sent against that user's account.
这是我迄今(从教程/职位拼凑在这里)
Here's what I have so far (cobbled together from tutorials / posts on here)
protected void btnSend_Click(object sender, EventArgs e)
{
//get a list of email addresses and send to them
//these will come from the database once testing comp
List<string> emails = new List<string>();
emails.Add("test1@test.com");
emails.Add("test2@test.com");
emails.Add("test3@test.com");
emails.Add("test4@test.com");
emails.Add("test5@test.com");
emails.Add("test6@test.com");
emails.Add("test7@test.com");
SendingDelegate worker = new SendingDelegate(DoSend);
AsyncCallback completedCallback = new AsyncCallback(DoSendCompletedCallBack);
lblThreadDetails.Text = "sending to " + emails.Count.ToString() + " email addresses";
worker.BeginInvoke(completedCallback, AsyncOperationManager.CreateOperation(null));
sending = true;
}
//boolean flag which indicates whether the async task is running
private bool sending = false;
private delegate bool SendingDelegate();
private bool DoSend()
{
//send messages
//emails sent here and saved in the DB each time
//give the user some feed back on screen. X should be the email address.
lblThreadDetails.Text = "processing " + x.ToString();
Thread.Sleep(1000);
return false;
}
private void DoSendCompletedCallBack(IAsyncResult ar)
{
//get the original worker delegate and the AsyncOperation instance
SendingDelegate worker = (SendingDelegate)((AsyncResult)ar).AsyncDelegate;
//finish the asynchronous operation
bool success = worker.EndInvoke(ar);
sending = false;
if (success)
{
//perform sql tasks now that crawl has completed
lblThreadDetails.Text = "all done!";
}
}
基本上,我需要把异步调用函数中一个循环,我通过电子邮件地址列表中。
I basically need to put the calling of the async function in to a loop where I go through the list of email addresses.
请问这种做法合理吗?
推荐答案
我presume您无法使用使用ASP.NET 4.5和异步/的await
,这可能是这种情况下的理想解决方案(参见<一href=\"http://www.hanselman.com/blog/TheMagicOfUsingAsynchronousMethodsInASPNET45PlusAnImportantGotcha.aspx\"相对=nofollow>这个并的这了解更多信息)。
I presume you're unable to use use ASP.NET 4.5 and async/await
, which might be an ideal solution to this case (see this and this for more info).
然而,随着ASP 4.0你仍然可以在网页上使用异步code用的 PageAsyncTask
和 Page.RegisterAsyncTask
。这将延长请求的续航时间,直到异步任务完成:
However, with ASP 4.0 you still can use asynchronous code on your page with PageAsyncTask
and Page.RegisterAsyncTask
. That would extend the life time of the request, until the async task has completed:
PageAsyncTask asyncTask = new PageAsyncTask(
slowTask.OnBegin, slowTask.OnEnd, slowTask1.OnTimeout,
"AsyncTaskName", true);
然后你从 OnBegin / OnEnd
引用 worker.BeginInvoke / EndInvoke会
。 MSDN有一个<一个href=\"http://msdn.microsoft.com/en-us/library/system.web.ui.pageasynctask%28v=vs.110%29.aspx?cs-save-lang=1&cs-lang=csharp#$c$c-snippet-2\"相对=nofollow>这个完整的示例code 。
Then you invoke worker.BeginInvoke/EndInvoke
from OnBegin/OnEnd
. MSDN has a complete sample code of this.
为了解决这个问题本身:
请问这种做法是否合理?感谢您的任何信息。
Does this approach make sense? thank you for any information.
我不认为这是有道理的,如果我明白你的code正确。
I don't think it makes sense, if I understood your code correctly.
显然,你在做什么这是一个启动后台线程,并在此线程做一些同步操作,如 Thread.sleep代码(1000)
你的<$ C内$ C> DoSend()。这将是有意义的客户端应用程序的用户界面(以保持UI响应)。
Apparently, what you're doing here is starting a background thread and doing some synchronous operation on this thread, like Thread.Sleep(1000)
inside your DoSend()
. That would make sense for a client side UI app (to keep the UI responsive).
不过,对于你的服务器端应用程序,你没有得到任何好处:至少有一个线程(一个开始的BeginInvoke
)的运行期间,仍然受阻。
However, for your server-side app, you're not getting any advantage: at least one thread (the one started with BeginInvoke
) remains blocked during your ongoing operation.
您不妨称之为 DoSend()
直接处理HTTP请求(在 btnSend_Click
原来的线程上),无的BeginInvoke
。在这种情况下,您的应用程序甚至可以缩放稍微好一点,因为它会较少线程切换。
You might as well call DoSend()
directly on the original thread that handles the HTTP request (inside btnSend_Click
), without BeginInvoke
. In that case, your app might even be scaling slightly better, because it'd have less thread switching.
现在,也许你可以重新的因素code使用不需要专用线程纯异步IO /网络绑定的API。这是什么使您的应用程序扩展好得多。阅读斯蒂芬·克利里的的没有线程的博客文章,得到什么我谈论的一个更好的图片。
Now, perhaps you can re-factor your code to use pure asynchronous IO/Network-bound APIs which do not require a dedicated thread. That's what would make your app scale much better. Read Stephen Cleary's There Is No Thread blog post, to get a better picture of what I'm talking about.
这篇关于里面asp.net V4环异步任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!