我正在尝试将我的方法变成可以异步调用的东西。
通常从AddQueue方法中,我只需调用WorkingSession类中的ListOfJobsInQueue方法,得到它的结果并完成它。
在这里使用我能找到的关于异步编程的信息,我已经完成了以下代码,但它似乎停留在 CurrentPageCode 属性调用上。
它甚至没有进入 MessageBox.Show(“Processing with with”+ queueResult.Count +“rows”); line。
有人可以协助并告诉我哪里出错了吗?
//Primary Class
public void AddQueue()
{
MessageBox.Show(GetJobsFromQueueAsync().Result.Count().ToString());
}
async Task<List<string>> GetJobsFromQueueAsync()
{
Task<List<string>> getJobsTask = WorkingSession.GetlistOfJobsAsync();
List<string> queueResult = await getJobsTask;
MessageBox.Show("Processing complete with " + queueResult.Count + " rows");
return queueResult;
}
//***
//WorkingSession Class
public Task<List<string>> GetlistOfJobsAsync()
{
return Task.Run<List<string>>(() =>
{
return ListOfJobsInQueue();
});
}
public List<string> ListOfJobsInQueue()
{
if (CurrentPageCode == "CS1")
{
List<string> actionList = new List<string>();
short pageNum = PageCurrent;
short pageMax = PageMax;
for (short atPage = pageNum; atPage <= pageMax; atPage++)
{
//Scan each job on the current queue page
for (int lineNum = 5; lineNum < 18; lineNum++)
{
string reference = GetJobText(new Coordinate { row = lineNum });
actionList.Add(reference);
}
//Once finished with this job page, goto the next
SendCMDKey(Mnemonic.F8);
}
return actionList;
}
else
{
return null;
}
}
//Other method / property signatures (for reference)
public string CurrentPageCode;
public bool SendCMDKey(Mnemonic command)
public string GetJobText(Coordinate coordinate)
//***
答案 0 :(得分:0)
死锁问题实际上是这种方法:
public void AddQueue()
{
MessageBox.Show(GetJobsFromQueueAsync().Result.Count().ToString());
}
Task.Wait
代码中应避免拨打Task<T>.Result
或async
。 I explain the deadlock in full on my blog,但摘要版本是await
将捕获上下文(在本例中为UI上下文)并尝试在该上下文中恢复其async
方法(在本例中为UI线程)。对于某些上下文(例如,UI上下文),如果您在该上下文中阻塞线程(例如,在UI线程上调用Task<T>.Result
),则async
方法无法在该上下文上恢复,从而导致死锁。
要解决此问题,请一直使用async
:
public async Task AddQueueAsync()
{
var jobs = await GetJobsFromQueueAsync();
MessageBox.Show(jobs.Count().ToString());
}
这段代码也不太理想,但是更加微妙:
public Task<List<string>> GetlistOfJobsAsync()
{
return Task.Run<List<string>>(() =>
{
return ListOfJobsInQueue();
});
}
通过在Task.Run
中包含整个方法的逻辑,你真正在做的是写一个假的异步&#34;方法。它有一个异步签名,但逻辑只是在后台线程上同步工作。
最好尽可能将Task.Run
用于推向UI层;保持它不受任何可重用的库方法的影响。让你的API说实话:拥有同步工作的同步签名。 I have a blog series that goes into detail
答案 1 :(得分:0)
我能做到的最简单
public async Task<int> GetWorkFlowStageAsync(string tracker,CancellationToken? token = null)
{
return await Task.FromResult(0);
}