簡體   English   中英

ASP.NET應用程序中任務的奇怪行為

[英]Weird behaviour of task in ASP.NET application

我試圖異步地從所有分支的Mysql服務器連接並接收非常少量的數據,而不必等待一個完成。

我有我自己的事件驅動的.NET MySQL Connector Wrapper庫,它可以正常工作而無需異步。

看起來我在執行多任務處理時缺少某些東西,但我不知道為什么。

public void GetALL()
    {
        TaskList = new Task[RemSQL.Count];

        Response.Write("<h1>starting..........</h1>");

        Task t;
        BranchInfo b;
        Wrapper w;

        for (int tx = 0; tx < RemSQL.Count; tx++)
        {
            int txx = tx; //strongly suggested on MSDN while using tasks/threads in loops
            b = RemSQL[txx];
            w = b.Wrapper;
            Response.Write("<h2>TASK #" + txx.ToString() + " branch.id #" + w.id + " starts...</h2>");

            w.Connecting += Wrapper_Connecting;            
            w.Connected += Wrapper_Connected;
            w.ConnectionError += Wrapper_ConnectionError;

            //w.Connect() //disabling multitasking works just fine

            t = new Task(() =>
            {
                w.Connect();
            });

            TaskList[txx] = t;
            t.Start();

        }

        Task.WaitAll(TaskList);

        Response.Write("<h1>Tasks completed</h1>");

        foreach(BranchInfo bb in RemSQL)
        {
            bb.Wrapper.Dispose();
        }

        Response.Flush();
        Response.End();

    }

    private void Wrapper_Connected(object sender)
    {
        Wrapper w = (Wrapper)sender;
        WriteScript("Connected('" + w.id + "');");
    }

    private void Wrapper_Connecting(object sender)
    {
        Wrapper w = (Wrapper)sender;
        WriteScript("Connecting('" + w.id + "');");
    }

    private void Wrapper_ConnectionError(object sender, Exception ex)
    {
        Wrapper w = (Wrapper)sender;
        WriteScript("ConnectionFailed('" + w.id + "', '" + ex.Message + "');");
    }

private void WriteScript(string scr)
{
    Response.Write("<script>" + scr + "</script>\n");
    Response.Flush();
}

這是輸出:

<h1>starting..........</h1><h2>TASK #0 branch.id #2 starts...</h2>
<h2>TASK #1 branch.id #3 starts...</h2>
<h2>TASK #2 branch.id #4 starts...</h2>
<h2>TASK #3 branch.id #5 starts...</h2>
<h2>TASK #4 branch.id #6 starts...</h2>
<h2>TASK #5 branch.id #7 starts...</h2>
<h2>TASK #6 branch.id #8 starts...</h2>
<h2>TASK #7 branch.id #9 starts...</h2>
<h2>TASK #8 branch.id #10 starts...</h2>
<h2>TASK #9 branch.id #11 starts...</h2>
<h2>TASK #10 branch.id #13 starts...</h2>
<h2>TASK #11 branch.id #14 starts...</h2>
<h2>TASK #12 branch.id #15 starts...</h2>
<h2>TASK #13 branch.id #16 starts...</h2>
<h2>TASK #14 branch.id #17 starts...</h2>
<h2>TASK #15 branch.id #19 starts...</h2>
<h2>TASK #16 branch.id #20 starts...</h2>
<script>Connecting('20');</script>
<script>Connecting('20');</script>
<script>Connecting('20');</script>
<script>Connecting('20');</script>
<script>Connecting('20');</script>
<script>Connecting('20');</script>
<script>Connecting('20');</script>
<script>Connecting('20');</script>
<script>Connecting('20');</script>
<script>Connecting('20');</script>
<script>Connecting('20');</script>
<script>Connecting('20');</script>
<script>Connecting('20');</script>
<script>Connecting('20');</script>
<script>Connecting('20');</script>
<script>Connecting('20');</script>
<script>Connecting('20');</script>
<script>ConnectionFailed('20', 'There is already an open DataReader associated with this Connection which must be closed first.');</script>
<script>ConnectionFailed('20', 'There is already an open DataReader associated with this Connection which must be closed first.');</script>
<script>ConnectionFailed('20', 'There is already an open DataReader associated with this Connection which must be closed first.');</script>
<script>ConnectionFailed('20', 'There is already an open DataReader associated with this Connection which must be closed first.');</script>
<script>ConnectionFailed('20', 'There is already an open DataReader associated with this Connection which must be closed first.');</script>
<script>ConnectionFailed('20', 'There is already an open DataReader associated with this Connection which must be closed first.');</script>
<script>ConnectionFailed('20', 'There is already an open DataReader associated with this Connection which must be closed first.');</script>
<script>ConnectionFailed('20', 'There is already an open DataReader associated with this Connection which must be closed first.');</script>
<script>ConnectionFailed('20', 'There is already an open DataReader associated with this Connection which must be closed first.');</script>
<script>Connected('20');</script>
<script>ConnectionFailed('20', 'There is already an open DataReader associated with this Connection which must be closed first.');</script>
<script>ConnectionFailed('20', 'There is already an open DataReader associated with this Connection which must be closed first.');</script>
<script>ConnectionFailed('20', 'There is already an open DataReader associated with this Connection which must be closed first.');</script>
<script>ConnectionFailed('20', 'There is already an open DataReader associated with this Connection which must be closed first.');</script>
<script>ConnectionFailed('20', 'There is already an open DataReader associated with this Connection which must be closed first.');</script>
<script>ConnectionFailed('20', 'There is already an open DataReader associated with this Connection which must be closed first.');</script>
<script>Connected('20');</script>
<h1>Tasks completed</h1>

如您所見,我想包裝器w總是會得到循環中最后一次調用的引用。 但是,當我注釋掉任務部分並直接在循環中使用w.Connect()時,一切都已修復。

有任何想法嗎 ?

您的問題是您正在關閉稍后要更改的局部變量w ,因此,當您執行任務時,它已經包含運行時的其他值。

解決方案很簡單:在循環內聲明tbw 實際上,如果我是您,我會將其重寫為簡單的Select

Response.Write("<h1>starting..........</h1>");
Task.WaitAll(
  RemSQL.Select(b => b.Wrapper).Select(w => TaskFactory.Run(() => {
        Response.Write("<h2>TASK #" + txx.ToString() + " branch.id #" + w.id + " starts...</h2>");

        w.Connecting += Wrapper_Connecting;            
        w.Connected += Wrapper_Connected;
        w.ConnectionError += Wrapper_ConnectionError;

        w.Connect();
  })).ToArray());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM