我从一个函数开始一个新的任务,但我不希望它在同一个线程上运行.我不关心它运行在哪个线程上,只要它是一个不同的线程(因此这个问题中给出的信息没有帮助).
我保证TestLock在允许Task t再次输入之前,以下代码将始终退出吗?如果没有,建议的设计模式是什么来防止再次出现?
object TestLock = new object();
public void Test(bool stop = false) {
Task t;
lock (this.TestLock) {
if (stop) return;
t = Task.Factory.StartNew(() => { this.Test(stop: true); });
}
t.Wait();
}
Run Code Online (Sandbox Code Playgroud)
编辑:基于Jon Skeet和Stephen Toub的以下答案,确定性地防止重入的一种简单方法是传递CancellationToken,如此扩展方法所示:
public static Task StartNewOnDifferentThread(this TaskFactory taskFactory, Action action)
{
return taskFactory.StartNew(action: action, cancellationToken: new CancellationToken());
}
Run Code Online (Sandbox Code Playgroud) 考虑在没有等待的情况下使用async.
想想也许你误解了异步的作用.警告是完全正确的:如果您将方法标记为异步但不在任何地方使用等待,那么您的方法将不是异步的.如果调用它,方法中的所有代码将同步执行.
我想编写一个应该运行异步但不需要使用await的方法.例如,当使用线程时
public async Task PushCallAsync(CallNotificationInfo callNotificationInfo)
{
Logger.LogInfo("Pushing new call {0} with {1} id".Fill(callNotificationInfo.CallerId,
}
Run Code Online (Sandbox Code Playgroud)
我想要调用PushCallAsync并运行异步,不想使用等待.
我可以在C#中使用async而无需等待吗?
我正在创建一个控制台程序,它可以通过模拟多个客户端来测试对Cache的读/写,并编写了以下代码.请帮我理解:
void Main()
{
List<Task<long>> taskList = new List<Task<long>>();
for (int i = 0; i < 500; i++)
{
taskList.Add(TestAsync());
}
Task.WaitAll(taskList.ToArray());
long averageTime = taskList.Average(t => t.Result);
}
public static async Task<long> TestAsync()
{
// Returns the total time taken using Stop Watch in the same module
return await Task.Factory.StartNew(() => // Call Cache Read / Write);
}
Run Code Online (Sandbox Code Playgroud) c# asynchronous load-testing task-parallel-library async-await
我正在努力学习如何在异步方法的世界中执行一些非常长时间运行的后台处理.
使用Stephen Cleary的博客中的词汇,我有兴趣在"承诺任务" 之后启动 "委托await任务".我希望尽快返回承诺的值,并让委托任务在后台继续.
为了处理uned await-ed委托任务中的异常,我将使用在此处描述的模型之后建模的异常处理延续.
public async Task<int> ComplexProcessAsync()
{
...
int firstResult = await FirstStepAsync();
// THE COMPILER DOESN'T LIKE THIS
Task.Run(() => VeryLongSecondStepIDontNeedToWaitFor(firstResult)).LogExceptions();
return firstResult;
}
Run Code Online (Sandbox Code Playgroud)
因为VeryLongSecondStep...()可能需要很多分钟,并且其结果纯粹是通过副作用(例如出现在数据库中的记录)可观察到的,所以我不愿意这样做await.
但正如所指出的,编译器并不喜欢这样.它警告说"Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call."
我可以忽略这个警告,但我觉得我不是以"正确"的方式做这件事.那么,什么是 …
这是我的情况,有2个类和我的主要表单Form1:
Class1:有一个方法doSomethingAndCall(callback)创建一个新线程Class2:具有动态创建的控件,带有一个触发Class1.doSomethingAndCall(newCallback)的按钮
在代码中它看起来像这样(它从Class2.Button_Click开始):
Class Class1
public shared sub doSomethingAndCallAsync(state as object)
Console.WriteLine(Form1.InvokeRequired) 'output: false
Console.WriteLine(Form1.IsHandleCreated) 'output: false
Form1.Invoke(state.callback) 'throws System.InvalidOperationException
end sub
public shared sub doSomethingAndCall(callback as object)
System.Threading.ThreadPool.QueueUserWorkItem(AddressOf doSomethingAndCallAsync, New With {.callback = callback})
end sub
End Class
Class Class2
Public Delegate Sub doSomethingDelegate()
Public Sub doSomething()
Console.WriteLine("success!")
End Sub
Public Sub Button_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Class1.doSomethingAndCall(New doSomethingDelegate(AddressOf doSomething))
End Sub
End Class
Run Code Online (Sandbox Code Playgroud)
我得到的确切例外是:
在创建窗口句柄之前,无法在控件上调用Invoke或BeginInvoke
并且我可以看到第4行中的console.WriteLine向我显示该表单实际上并未创建.所以我添加了这个处理程序,现在它真的很混乱:
Private Sub Form1_HandleCreated(sender As Object, e As System.EventArgs) Handles …Run Code Online (Sandbox Code Playgroud) c# ×4
async-await ×3
.net ×1
asynchronous ×1
c#-5.0 ×1
invoke ×1
load-testing ×1
locking ×1
task ×1
vb.net ×1
winforms ×1