我是多线程环境中开发Win Forms应用程序的新手。请在以下情况下提供帮助。我想要解决这个问题的简单方法,如果 DataGrid 不适用于这种情况,我准备更改我的控件。
我正在从多个线程调用一个方法(异步操作),该方法在WinForms应用程序的数据网格中添加数据。调用此方法后,线程不会立即退出。由于 UI 阻止了所有线程,因此我收到异常"线程池中没有用于执行操作的空闲线程"
对于少数线程,它工作正常。但是当我把它扔到 1000 个线程时。UI 没有响应,我收到异常。
public static void PostAsync(string url, Object postParameters,
Action<HttpWebRequestCallbackState> responseCallback, object state,
string contentType = "application/json")
获取要在 UI 上显示的必需参数,并将其传递给 AsyncDelegate 内部的 Assert 方法。
HttpSocket.PostAsync(URL, requestData, callbackState =>
{
try
{
if (callbackState.Exception != null)
throw callbackState.Exception;
String response = HttpSocket.GetResponseText(callbackState.ResponseStream);
Assert(expectedData, responseObj, methodName + TrimFileName(requestInfo[1].ToString()), duration, err);
File.WriteAllText(responceJsonFilePath, response);
}
catch (Exception e)
{
String err = e.Message.ToString();
TimeSpan duration = new TimeSpan(0, 0, 0);
List<Object> requestInfo = callbackState.State as List<Object>;
String methodName = System.Reflection.MethodInfo.GetCurrentMethod().Name.Split(new char[] { '<', '>' })[1];
Assert(null, "Exception", methodName + TrimFileName(requestInfo[1].ToString()), duration, err);
}
// Assert Method calls refreshResult after performing some comparison
public static void refreshResult(string text, string testMethod, TimeSpan duration, String err)
{
JSONTest form = (JSONTest)Application.OpenForms["JSONTest"];
if (form.GridTestReport.InvokeRequired)
{
refreshCallback d = new refreshCallback(refreshResult);
form.Invoke(d, new object[] { text, testMethod, duration, err });
}
else
{
form.GridTestReport_resultTable.Rows.Add(testMethod, text, duration, err);
form.GridTestReport.Refresh();
if (text == "FAIL")
{
form.GridTestReport.Rows[form.GridTestReport.RowCount - 1].DefaultCellStyle.ForeColor = Color.Red;
}
else if (text == "PASS")
{
form.GridTestReport.Rows[form.GridTestReport.RowCount - 1].DefaultCellStyle.ForeColor = Color.Green;
}
}
}
不应仅使用多线程来处理 UI 更新。UI 工作始终仅适用于一个线程。因此,如果您决定通过从不同线程更新 UI 来加快应用程序的速度,它将不起作用(因为这显然是不可能的,并且您的更新将排队在 UI 线程上执行)。应该将多个线程用于一些真正的异步操作或一些 CPU 繁重的工作。如果您有很多 UI 更新,您可以做的是有一些计时器,例如,它将一次性刷新所有 UI 更新,而不是 N 个小的更改。例如,如果要向网格添加行,则可以冻结网格,添加所有新行,然后解冻它。