2015-12-21 69 views
0

我是C#的新手,需要一些幫助。應用程序凍結,然後立即顯示所有內容

在我的應用程序,我想顯示某種類型的日誌消息的前幾個相當長運行的任務(例如「啓動任務1」),以顯示該腳本是在這個過程中。

,而不是做什麼,但:顯示日誌,做任務,顯示日誌,做下任務等應用程序凍結,不顯示任何內容,那麼一旦所有的「重」任務完成後,它會顯示每個日誌。

我本來以爲它會顯示一個日誌,那麼一個任務期間凍結,然後顯示另一個日誌,併爲下一個任務再次凍結,而是它有權在函數的開始凍結。

這是我的代碼示例:

public void Work(string src, string spl) 
{ 
    log("======================="); 
    string cmd = ...; // some arguments for external exe 

    var proc = new System.Diagnostics.Process 
    { 
     StartInfo = new System.Diagnostics.ProcessStartInfo 
     { 
      FileName = ..., // some external app 
      Arguments = cmd, 
      UseShellExecute = false, 
      RedirectStandardOutput = false, 
      CreateNoWindow = true 
     } 
    }; 

    log("Task 1 started. Please wait..."); 
    proc.Start(); 
    proc.WaitForExit(); 
    proc.Close(); 
    log("Task 1 done."); 
} 

public void log(string message) 
{ 
    ScrollContent.Text += "\n" + message; 
} 

現在我正在學習有關線程和任務類,但它似乎並沒有工作。我已經試過這樣:

public void Work(string src, string spl) 
{ 

    // same as before 

    log("Task 1 started. Please wait..."); 

    Task.Factory.StartNew(() => StartProc(proc)).Wait; 

    log("Task 1 done."); 
} 

public void StartProc(System.Diagnostics.Process proc) 
{ 
    proc.Start(); 
    proc.WaitForExit(); 
    proc.Close(); 
} 

所以它可以做的重任在另一個線程,但不,它仍然凍結在函數的開始,直到把它完成。我可能做了完全錯誤的事情,但我不知道該怎麼做。

謝謝。

+1

MSDN:「在等待方法塊調用調用線程,直到一個類的實例已經完成執行。」 – Spawn

回答

2

當您使用Wait這樣,你正在等待進程結束,而不是同步異步。您應該將您的工作方法更改爲:

public async Task Work(string src, string spl) 
{ 

    // same as before 

    log("Task 1 started. Please wait..."); 

    await Task.Factory.StartNew(() => StartProc(proc)); 

    log("Task 1 done."); 
} 

它將異步阻止進度。

+0

這似乎工作,謝謝! – JDoe

+2

如果您正在使用異步/等待你真的應該使用'Task.Run(',而不是'Task.Factory.StartNew(',如果你使用的任務工廠你真正需要明確有關的TaskScheduler,因爲它的默認行爲可以很容易地導致你的程序在UI線程上運行你不期望的東西。 –