我在我创建的DLL中有一个函数,它执行SQL命令并返回执行它们的路径文件,有错误的命令数和3 pos中成功执行的命令数。阵列。 问题是它只会在foreach结束时返回,只允许我以最后执行文件的形式出现在文本框中,并且我需要在执行时显示文件路径。
我需要一种方法在每次foreach迭代时返回数组,但保持>函数处于活动状态,以便执行下一个>文件中的其余命令,这是函数:
public string[] ExecuteCommands(string Directoria, CdpsiUpdateSql Updater, CdpsiUpdateSqlparser parser, string Log)
{
string[] numArray1 = new string[3];
List<string> list = ((IEnumerable<string>)Directory.GetFiles(Directoria, "*.sql", SearchOption.TopDirectoryOnly)).Select(f =>
{
string[] strArray = Path.GetFileName(f).Split('_');
int result;
if (strArray.Length < 1 || !int.TryParse(strArray[0], out result))
result = -1;
var data = new
{
File = f,
Version = result
};
return data;
}).Where(f => f.Version > -1).OrderBy(f => f.Version).Select(f => f.File).ToList<string>();
foreach (string str in list)
{
int[] numArray2 = this.ExecuteCommand(parser.Parser(str), Updater, str, Log);
int Certos = Convert.ToInt32(numArray1[0]);
int Errados = Convert.ToInt32(numArray1[1]);
Certos += numArray2[0];
Errados += numArray2[1];
numArray1[0] = Certos.ToString();
numArray1[1] = Errados.ToString();
numArray1[2] = str;
}
return numArray1;
}
任何帮助都会得到很好的帮助,谢谢
使用yield?
public IEnumerable<string []> ExecuteCommands(string Directoria, CdpsiUpdateSql Updater, CdpsiUpdateSqlparser parser, string Log)
{
string[] numArray1 = new string[3];
List<string> list = ((IEnumerable<string>)Directory.GetFiles(Directoria, "*.sql", SearchOption.TopDirectoryOnly)).Select(f =>
{
string[] strArray = Path.GetFileName(f).Split('_');
int result;
if (strArray.Length < 1 || !int.TryParse(strArray[0], out result))
result = -1;
var data = new
{
File = f,
Version = result
};
return data;
}).Where(f => f.Version > -1).OrderBy(f => f.Version).Select(f => f.File).ToList<string>();
foreach (string str in list)
{
int[] numArray2 = this.ExecuteCommand(parser.Parser(str), Updater, str, Log);
int Certos = Convert.ToInt32(numArray1[0]);
int Errados = Convert.ToInt32(numArray1[1]);
Certos += numArray2[0];
Errados += numArray2[1];
numArray1[0] = Certos.ToString();
numArray1[1] = Errados.ToString();
numArray1[2] = str;
yield return numArray1;
}
//return numArray1;
}
答案 0 :(得分:2)
首先,我会为结果定义一个更好的类型:
g_signal_connect(splitmuxsink, "format-location",
G_CALLBACK (on_format_location), NULL);
...
gchar* on_format_location(GstSplitMuxSink *splitmux, guint fragment_id,
gpointer user_data);
然后你可以在你的dll方法中添加一个IProgress<T>
参数:
并将此作为dll方法的额外参数:
error: unknown type name ‘GstSplitMuxSink’
在调用网站上,您可以像这样创建Progress<T>
的实例:
public struct Result
{
public string File;
public int Errors;
public int Successes;
}
并实现类似的public void ExecuteCommands(string Directoria, CdpsiUpdateSql Updater, CdpsiUpdateSqlparser parser, string Log, IProgress<Result> progress)
{
//... your code
foreach (string str in list)
{
int[] numArray2 = this.ExecuteCommand(parser.Parser(str), Updater, str, Log);
// your code
Result result = new Result
{
File = str,
Error = Errados,
Successes = Certos
};
progress.Report(result);
}
}
方法:
Progress<Result> progress = new Progress<Result>(HandleProgress);
ExecuteCommands(Directoria, Updater, parser, Log, progress);
注意但是HandleProgress
同步运行 。因此,您的UI线程被阻止,并且不会立即绘制对控件的更改。因此我添加了private void HandleProgress(Result result)
{
/* use the values in result to update your UI */
Refresh(); // refresh the controls you updated
}
语句,但其确切的实现取决于您即将更新的控件。
ExecuteCommands
方法也很好。但我仍然会建议一个合适的Refresh()
类型。您的方法的使用者永远不会知道该字符串数组中包含哪些信息。被阻止的UI线程的问题将是相同的。
答案 1 :(得分:0)
您可以将return语句移动到foreach循环中并使用yield
foreach (string str in list)
{
int[] numArray2 = this.ExecuteCommand(parser.Parser(str), Updater, str, Log);
int Certos = Convert.ToInt32(numArray1[0]);
int Errados = Convert.ToInt32(numArray1[1]);
Certos += numArray2[0];
Errados += numArray2[1];
numArray1[0] = Certos.ToString();
numArray1[1] = Errados.ToString();
numArray1[2] = str;
yield return numArray1;
}
答案 2 :(得分:0)
只是为您提供一些替代方案。您可以尝试使用delegate / lambda
public void ExecuteCommands(string Directoria, CdpsiUpdateSql Updater, CdpsiUpdateSqlparser parser, string Log, Action<int[]> getResults)
{
string[] numArray1 = new string[3];
List<string> list = ((IEnumerable<string>)Directory.GetFiles(Directoria, "*.sql", SearchOption.TopDirectoryOnly)).Select(f =>
{
string[] strArray = Path.GetFileName(f).Split('_');
int result;
if (strArray.Length < 1 || !int.TryParse(strArray[0], out result))
result = -1;
var data = new
{
File = f,
Version = result
};
return data;
}).Where(f => f.Version > -1).OrderBy(f => f.Version).Select(f => f.File).ToList<string>();
foreach (string str in list)
{
int[] numArray2 = this.ExecuteCommand(parser.Parser(str), Updater, str, Log);
int Certos = Convert.ToInt32(numArray1[0]);
int Errados = Convert.ToInt32(numArray1[1]);
Certos += numArray2[0];
Errados += numArray2[1];
numArray1[0] = Certos.ToString();
numArray1[1] = Errados.ToString();
numArray1[2] = str;
//new code
if(getResults!=null)
{
getResults(numArray1);
}
}
}
主要电话中的用法将是:
int totalResults=0;
Action<int[]> doSomething = (results)=>
{
//do some work whenever results is returned, e.g
totalResults+=results.Sum();
};
ExecuteCommands(directoria, parser, updater, log, doSomething);