2015-10-02 3 views
2

Я пытаюсь подключиться и получать очень маленький объем данных из серверов Mysql из всех филиалов асинхронно, не дожидаясь завершения.Странное поведение задачи в приложении ASP.NET

У меня есть своя библиотека событий, основанная на событиях .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.Connect() непосредственно в цикле, все это исправляется.

Любые идеи?

ответ

4

Ваша проблема заключается в том, что вы закрываете локальную переменную w, которую вы меняете позже, поэтому к тому времени, когда вы дошли до задачи, она уже содержит другое значение, которое было во время работы.

И решение прост: объявить t, b и w внутри цикла. На самом деле, если бы я был вами, я бы переписал его простым Select:

+0

большое спасибо. не могу поверить, что я пропускаю то, чего не было, когда использую счетчик «txx», то же самое. –

Смежные вопросы