所有我在WinForm C#應用程序運行時調用一個包含WinForm的.NET DLL。要做到這一點我使用以下內容:在運行時調用一個多線程的DLL
DLL = Assembly.LoadFrom(strDllPath);
classType = DLL.GetType(String.Format("{0}.{1}", strNamespaceName, strClassName));
if (classType != null)
{
if (bDllIsWinForm)
{
classInst = Activator.CreateInstance(classType);
Form dllWinForm = (Form)classInst;
dllWinForm.Show();
// Invoke required method.
MethodInfo methodInfo = classType.GetMethod(strMethodName);
if (methodInfo != null)
{
object result = null;
result = methodInfo.Invoke(classInst, new object[] { dllParams });
return result == null ? String.Empty : result.ToString();
}
}
}
這是調用WinForm DLL和所需的方法罰款的DLL內的串行方法。不過,我現在調用一個多線程的DLL,並調用下面的方法:
public async void ExecuteTest(object[] args)
{
Result result = new Result();
if (!BuildParameterObjects(args[0].ToString(), args[1].ToString()))
return;
IProgress<ProgressInfo> progressIndicator = new Progress<ProgressInfo>(ReportProgress);
List<Enum> enumList = new List<Enum>()
{
Method.TestSqlConnection,
Method.ImportReferenceTables
};
Task task = Task.Factory.StartNew(() =>
{
foreach (Method method in enumList)
{
result = Process.ProcessStrategyFactory.Execute(Parameters.Instance, progressIndicator,
Process.ProcessStrategyFactory.GetProcessType(method));
if (!result.Succeeded)
{
// Display error.
return;
}
}
});
await task;
Utilities.InfoMsg("VCDC run executed successfully.");
}
但是,這是由於await
控制權返回給調用者的時候了(預計)。但是,返回會導致調用方法退出,從而關閉DLL WinForm。
什麼是保持DLL WinForm活動/打開的最佳方法?
謝謝你的時間。
編輯。繼斯蒂芬的建議之下,我決定把我的DLL intery方法類型Task<object>
併成立了延續如下
if (classType != null)
{
if (bDllIsWinForm)
{
// To pass object array to constructor use the following.
// classInst = Activator.CreateInstance(classType, new object[] {dllParams});
classInst = Activator.CreateInstance(classType);
dllWinForm = (Form)classInst;
dllWinForm.Show();
// Invoke required method.
MethodInfo methodInfo = classType.GetMethod(strMethodName);
if (methodInfo != null)
{
object result = null;
result = methodInfo.Invoke(classInst, new object[] { dllParams });
if (result != null)
{
if (result.GetType() == typeof(Task<object>))
{
Task<object> task = (Task<object>)result;
task.ContinueWith(ant =>
{
object innerResult = task.Result;
return innerResult == null ? String.Empty : innerResult.ToString();
});
}
return result.ToString();
}
return String.Empty;
}
}
}
我決定成立的延續,而不是await
避免鏈接是。將與await
關鍵字出現 - 即拍即調用方法(即調用Task<String>
型等調用堆棧的DLL
DLL入口方法現在變成了:
public Task<object> ExecuteTest(object[] args)
{
Task<object> task = null;
Result result = new Result();
if (!BuildParameterObjects(args[0].ToString(), args[1].ToString()))
return task;
IProgress<ProgressInfo> progressIndicator = new Progress<ProgressInfo>(ReportProgress);
List<Enum> enumList = new List<Enum>()
{
Method.TestSqlConnection,
Method.ImportReferenceTables
};
task = Task.Factory.StartNew<object>(() =>
{
foreach (Method method in enumList)
{
result = Process.ProcessStrategyFactory.Execute(Parameters.Instance, progressIndicator,
Process.ProcessStrategyFactory.GetProcessType(method));
if (!result.Succeeded)
{
// Display error.
}
task.Wait(5000); // Wait to prevent the method returning too quickly for testing only.
}
return null;
});
return task;
}
但是,這會導致DLL WinForm顯示一秒鐘,然後disapear。我甚至試圖讓全球範圍內的對象保持活動狀態,但這也不起作用。我想要注意的是,調用DLL(N.B.的調用方法已經在後臺線程池線程上運行)。
任何進一步有助於理解。
試圖不打開門:不要關閉它。樣板是BackgroundWorker.RunWorkerCompleted和TaskScheduler.FromCurrentSynchronizationContext在工作完成後在UI線程上運行代碼。 – 2013-05-09 11:40:53
對不起,我不明白你的意思@HansPassant。感謝您的時間... – MoonKnight 2013-05-09 12:30:58
@HansPassant BackgroundWorker或多或少已經過時並被視爲遺留問題。除了對Task和Progress的簡單調用,不能提供異步的詳細進度,不能用於鏈接多個異步調用,不能使用ThreadPool,不能利用異步方法,不能... – 2013-05-09 13:51:30