这是一个非常简单的示例,可以在互联网上找到 Async / Await 概念,我想知道如何使用开始/结束调用来实现这个小逻辑? 我需要做的就是使用两种方法( Async / Await和delegates )准备一个复杂的逻辑,所以我想从一个基本的工作流程开始。
int countCharacters()
{
int count = 0;
using (StreamReader reader= new StreamReader("D:\\Data.txt"))
{
string content = reader.ReadToEnd();
count = content.Length;
Thread.Sleep(5000);
}
return count;
}
private async void btnProcessFIle_Click(object sender, EventArgs e)
{
Task<int> task = new Task<int>(countCharacters);
task.Start();
int count = await task;
lblCount.Text = "No. of characters in file=" +Environment.NewLine+ count.ToString();
}
答案 0 :(得分:2)
这是一个非常简单的例子,可以在互联网上找到Async / Await概念
这是一个非常糟糕的例子。
它使用任务构造函数和Start
,这是一个明确的禁忌(实际上有没有有效用例)。
它还在&#34; async示例&#34;中的后台线程上同步使用文件系统。
如果你想要一个如何异步使用同步(例如,CPU绑定)代码的例子,那么这是一个更好的例子,几乎可以做同样的事情:
int countCharacters()
{
Thread.Sleep(5000);
return 13;
}
private async void btnProcessFIle_Click(object sender, EventArgs e)
{
var count = await Task.Run(() => countCharacters());
lblCount.Text = "No. of characters in file=" + count;
}
请注意,这是如何异步调用UI线程中的CPU绑定代码的示例 - 不是&#34;异步概念& #34;
我想知道如何使用Begin / End Invoke实现这个小逻辑?
由于您的工作是在后台线程上同步工作,这实际上非常简单; you can just use Delegate.BeginInvoke
而不是创建自己的IAsyncResult
(这是关于APM的非常难的部分 - 如果你确实需要实现它,请参阅&#34;实现CLR异步编程模型&#34;在{ {3}})。
但是既然你可以使用Delegate.BeginInvoke
,那就非常简单了:
private void btnProcessFIle_Click(object sender, EventArgs e)
{
var ui = SynchronizationContext.Current;
Func<int> d = countCharacters;
d.BeginInvoke(CountCharactersCallback, ui);
}
private void CountCharactersCallback(IAsyncResult ar)
{
var d = (Func<int>) ((AsyncResult) ar).AsyncDelegate;
var ui = (SynchronizationContext) ar.AsyncState;
try
{
var count = d.EndInvoke(ar);
ui.Post(CountCharactersComplete, count);
}
catch (Exception ex)
{
var edi = ExceptionDispatchInfo.Capture(ex);
ui.Post(CountCharactersError, state);
}
}
private void CountCharactersComplete(object state)
{
var count = (int) state;
lblCount.Text = "No. of characters in file=" + count;
}
private void CountCharactersError(object state)
{
var edi = (ExceptionDispatchInfo)state;
edi.Throw();
}
注意:
CountCharactersCallback
是一个&#34;裸露的回调&#34;。从CountCharactersCallback
传播的任何异常都表示发生了灾难性错误。EndInvoke
的异常传播出BeginInvoke
回调。这是一个常见的错误。SynchronizationContext
同步回UI线程。这与await
的行为相同。ExceptionDispatchInfo
来保留跨线程的异常堆栈跟踪(不需要包装器异常)。CountCharactersError
只是直接在消息循环上引发异常。这与async void
的行为相同。答案 1 :(得分:0)
功能BeginInvoke可以访问非UI线程中的UI元素,因此您需要像这样更改代码:
for(var k=0; k < mdmid_array_implode_array_st.length; k++){
var mdmid_arr=mdmid_array_implode_array_st[k];
pool.query("select sum(cnt_deal_amt) as cnt_deal_amt from crm_clients_feedback_log where cnt_mdm_id IN ("+mdmid_arr+") ORDER BY cnt_mdm_id ASC",function(dealerr,dealrslt){
dealrslt_sa=dealrslt[0].cnt_deal_amt;
console.log(dealrslt);
})
}
OUtPUT:
[ RowDataPacket { cnt_deal_amt: 512529 } ]
[ RowDataPacket { cnt_deal_amt: 33000 } ]
[ RowDataPacket { cnt_deal_amt: null } ]
[ RowDataPacket { cnt_deal_amt: 1000 } ]
[ RowDataPacket { cnt_deal_amt: null } ]
[ RowDataPacket { cnt_deal_amt: 43600 } ]
[ RowDataPacket { cnt_deal_amt: 0 } ]
[ RowDataPacket { cnt_deal_amt: 0 } ]
[ RowDataPacket { cnt_deal_amt: 9500 } ]
[ RowDataPacket { cnt_deal_amt: null } ]
[ RowDataPacket { cnt_deal_amt: null } ]
[ RowDataPacket { cnt_deal_amt: 11500 } ]
答案 2 :(得分:-1)
没有异步/等待的代码。您不需要使用BeginInvoke,因为您可以使用curl
TaskScheduler.FromCurrentSynchronizationContext()
如果你真的想使用BeginInvoke我想你可以写
int countCharacters()
{
int count = 0;
using (StreamReader reader= new StreamReader("D:\\Data.txt"))
{
string content = reader.ReadToEnd();
count = content.Length;
Thread.Sleep(5000);
}
return count;
}
private void btnProcessFIle_Click(object sender, EventArgs e)
{
Task<int> task = new Task<int>(countCharacters);
task.Start();
var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
task.ContinueWith(count =>{
lblCount.Text = "No. of characters in file=" +Environment.NewLine+ count.ToString();
}, uiScheduler);
}