能否请您告诉我将await
关键字放在此行代码中用于在文本文件中搜索字符串的位置。
搜索正在进行时,我的应用程序冻结。
private async void BtnCheckLogs_OnClick(object sender, RoutedEventArgs e)
{
_rowCount = await CheckInLogs();
Header.Text = $@"Not found tag Count: {_rowCount}";
}
private async Task<int> CheckInLogs()
{
IList<ManualReadTag> result = new List<ManualReadTag>();
var notFoundTag = 0;
if (_rowCount == 0)
{
MessageBox.Show("There are no tag to compare from the logs");
return 0;
}
else
{
var dataTable = ToDataTable(_manualReadTagList);
if (dataTable != null)
{
string[] lines = null;
string currentAddress = null;
foreach (DataRow row in dataTable.Rows)
{
var plaza = row[0].ToString();
var lane = row[1].ToString();
var tagNumber = row[3].ToString();
var originalTrxnDtime = row[2];
var trxnDtime = Convert.ToDateTime(row[2]).ToShortDateString();
var year = trxnDtime.Split('/')[2];
var month = trxnDtime.Split('/')[1].PadLeft(1,'0');
var day = trxnDtime.Split('/')[0].PadLeft(1, '0'); ;
var obj = JObject.Parse(json);
var search = $@"{plaza}.Lanes.{lane}.Ip";
var ipAddress = (string)obj.SelectToken(search);
using (new ImpersonateUser("IETCADMIN", "", "M1nion$"))
{
var dir = @"i\RFIDServiceLogs";
var fileName = $@"\\{ipAddress}\{dir}\{year}\{month}\{day}\RfidHandlerSystemLogs.txt";
var pattern = tagNumber;
var isFound = false;
try
{
using (var reader = new StreamReader(fileName))
{
string currentLine;
while ((currentLine = reader.ReadLine()) != null)
{
if (currentLine.Contains(tagNumber))
{
isFound = true;
break;
}
}
}
if (!isFound)
{
var mrt = new ManualReadTag
{
Plaza = Convert.ToInt16(plaza),
Lane = Convert.ToInt16(lane),
Tag_Number = tagNumber,
Trxn_DTime = Convert.ToDateTime(originalTrxnDtime)
};
result.Add(mrt);
notFoundTag++;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
ViewingGridFromComparison.ItemsSource = result;
}
}
return notFoundTag;
}
感谢您的帮助。使用这个关键字真的很难。如果您能解释的话,那就更好了。
答案 0 :(得分:2)
问题在于您的异步方法实际上并未执行任何异步工作,因此,它不会异步执行。 here回答了类似的问题。
如果要强制执行另一个任务,可以这样调用它:
_rowCount = await Task.Run(async () => await CheckInLogs());
这是一个快速的解决方案,但它也可以解决其他问题(最后有更多问题)。
其他一些选择是:
使方法同步(返回int
而不是Task<int>
),并在不同的任务中使用Task.Run(() => CheckInLogs())
显式运行该方法
实际上是在方法内部进行一些异步工作,即使用ReadLineAsync
方法而不是ReadLine
(docs)
使用ReadLineAsync :即使使用ReadLineAsync
并等待它会在另一个任务中执行该方法(即使其真正异步),您 发现调用线程最初仍处于阻塞状态。
在第一个await
之前之前执行一些需要一些时间才能完成的代码,并且由于尚未达到await
,因此之前的代码可能会发生它同步运行。
在您的代码中,行var dataTable = ToDataTable(_manualReadTagList);
可能足够慢以导致此行为,但这取决于此函数的实际实现。
在这种情况下,将方法调用为
await Task.Run(async () => await CheckInLogs());
即使该方法实际上在某个时候正在做一些异步工作,因为它会强制在另一个任务中立即运行该方法。
答案 1 :(得分:0)
您的代码正在同步运行,因为您的CheckInLogs方法未使用await运算符。 您的阅读是同步的,正如@SLaks在评论中所说,我将使用ReadLineAsync:https://docs.microsoft.com/en-us/dotnet/api/system.io.streamreader.readlineasync?view=netframework-4.8
我确定您可以在代码中看到此消息:)