异步方法中的代码库是这样的:
Thread.Sleep(500);
Run Code Online (Sandbox Code Playgroud)
一位同事将其重构为这样:
Task.Delay(500).Wait();
Run Code Online (Sandbox Code Playgroud)
考虑到相对较小的延迟,使用异步版本真的有优势吗(Task.Delay())?
如果延迟是几毫秒或几秒,它会改变吗?
更重要的是......击败他不是.Wait()为了异步吗?
为了提供更多上下文,这是在平均每分钟运行一次的后台进程中执行的。
第二种方法不是浪费更多资源吗?(正如这里的一些评论似乎表明的那样)
我目前正在使用.NET 4和Visual Studio 2010.MSDN表示Task.Delay在此版本的.NET框架中不可用.
但是,在我的系统中,ILdasm显示Task.Delay在mscorlib(4.0.0.0)中存在.所以我测试使用反射:
typeof (Task).GetMethod("Delay", new []{typeof (int)})
.Invoke(null, new object[]{1000});
Run Code Online (Sandbox Code Playgroud)
这似乎适用于我的电脑.所以我的问题是:
这是否意味着微软以某种方式提供了这种方法,但它们只是隐藏了它?
使用包装函数以上述方式使用它是否安全?更确切地说,这是否适用于仅安装了.NET 4的其他计算机?(我的系统是Windows 7)
UPDATE
我忘了天气或者没有安装.NET 4.5.所以我从控制面板检查.是的,安装了.NET 4.5.1.
我想知道 Task.delay Task.Wait 和 Thread.sleep 之间的区别
当我们使用thread.sleep时。从睡眠中唤醒后,将创建一个新堆栈。请让我告诉我它们之间真正的区别是什么。
我正在重构代码,该代码使用Thread.Sleep越来越长的时间限制来在出现错误时重试 SQL 查询。阻塞的常见替代Thread.Sleep似乎是await Task.Delay,这需要将方法更改为async. 该方法现在如下所示(为简洁起见,删除了额外的错误检查):
private static async Task<int> PrepareForRetry( int retryCount, SqlCommand command, int timeout )
{
++retryCount;
if (retryCount < ConnectionRetryCount)
{
int SleepTime = _connectionRetryBackoffTimes[retryCount - 1] + (_connectionRetryRandomBackoff.Next() % 500);
//Thread.Sleep(SleepTime);
await Task.Delay(SleepTime);
}
return retryCount;
}
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是async要求调用方法为async,等等。虽然最终重构为完全异步,但这远远超出了当前的重构范围。
我遇到的问题是如何从同步代码调用该方法并获取结果。使用
retryCount = PrepareForRetry(retryCount, command, timeout).Result;
Run Code Online (Sandbox Code Playgroud)
由于 UI 线程正在调用该方法,因此会造成死锁。我发现我可以通过将我的更改Task.Delay为
await Task.Delay(SleepTime).ConfigureAwait(false);
Run Code Online (Sandbox Code Playgroud)
但我不完全明白这是做什么的。我也尝试过使用调用该方法
retryCount = Task.Run(async () => { await PrepareForRetry(retryCount, command, timeout).Result; });
Run Code Online (Sandbox Code Playgroud)
但这有错误“'int'不包含'GetAwaiter'的定义”,并且我无法找出如何继续获得结果。使用 …
我能够通过输入表单Stephen Cleary解决问题.请参阅更新3.
我有一个Windows窗体应用程序,其中包含一个带有async修饰符的方法.如果在按钮的click事件中调用该方法,则它不会阻止UI线程.但是,当我在计时器内调用它作为回调时,它会冻结UI.我无法弄清楚我在这里做错了什么.请看下面我的代码.这只是一个用于演示目的的示例项目.
public Form1()
{
InitializeComponent();
}
private async void formCloseAsync()
{
shutdown stf = new shutdown();
stf.StartPosition = FormStartPosition.CenterScreen;
stf.Show();
var task = Task.Factory.StartNew(processClose);
await task;
}
private void processClose()
{
Thread.Sleep(5000);
Environment.Exit(1);
}
private void simpleButtonAsync_Click(object sender, EventArgs e)
{
formCloseAsync();
}
private void _simpleButtonTimer_Click(object sender, EventArgs e)
{
Timer _shutdownTimer = new Timer(delegate
{
formCloseAsync();
}, null, 5000, Timeout.Infinite);
}
Run Code Online (Sandbox Code Playgroud)
更新1:谢谢大家的宝贵意见.请参阅下面的更新代码
public Form1()
{
InitializeComponent();
}
private Timer _shutdownTimer;
private void formCloseAsync()
{
shutdown stf = …Run Code Online (Sandbox Code Playgroud) c# ×3
.net ×2
asynchronous ×2
task ×2
async-await ×1
c#-4.0 ×1
thread-sleep ×1
timer ×1
winforms ×1