I am having a problem with setting referenced variable inside of thread.
Error:"Cannot use ref or out parameter 'output' inside an
anonymous method, lambda expression, or query expression"
Is there any way to get this to work or achieve similar effect?
public static void LoadThreaded<T>(string path, ref T output)
{
ThreadStart threadStart = delegate
{
output = Loader<T>(path);
};
new Thread(threadStart).Start();
}
The problem is that the method returns prior to the output variable being set (necessarily), as the output is set by a different thread.
The best option here would be to use the TPL to rework this, ie:
Task<T> LoadThreaded<T>(string path)
{
return Task.Factory.StartNew( () => Loader<T>(path) );
}
This allows you to start this asynchronous operation, and get the result when it completes, either by blocking (calling output.Result) or by adding a task continuation.
Related
I need to get the returned value without await operator(in below sample I need to get the "hello world" in var y without await operator). Because one method is referred to a lot of places.But my requirement is that method is executed at asynchronously for particular operations. None other time it is enough to be executed as synchronously.
If I put await in all referred places that method needs to change as async and also referred methods need to change as async and await.
Is there any possibility to get the returned value?
Please find below sample code snippet:
class Program
{
static void Main(string[] args)
{
var x = getString();
}
public static async Task<string> getString()
{
var y = await GetString2();
return y;
}
public static async Task<string> GetString2()
{
return "hello world";
}
}
Here is there any possibility to get "hello world" string in var y without await operator?
Are you looking for something like that;
var str = GetString2().Result;
Result blocks the calling thread until the asynchronous operation is complete; it is equivalent the Wait method. await has asynchronous wait for the task completion.
Also, as #Sir Rufo and #MistyK described, you will get AggregateException on a possible exception, so it would be better to use GetAwaiter like this;
var str = GetString2().GetAwaiter().GetResult();
I wouldn't use Result because If error is thrown, you'll get AggregateException. It's better to do this:
var str = GetString2().GetAwaiter().GetResult()
You have one of two options:
Either use the Result property of the task. This has the downside that it can block the message pump and cause problems. In a console app this might work, but you need to test.
GetString2().Result;
Use the ContinueWith method to pass an action to perform when the task is complete. The disadvantage being you will not have access to the data immediately, and the calling function will return.
GetString2().ContinueWith(result => Console.WriteLine(result));
I'm trying to pass HttpContext.Current to the thread created via Task.Run. As I have a Transaction ID in in HttpContext.Items, which I'll need in the thread.
public static Task<TResult> RunWithContext<TResult>(Func<TResult> function)
{
var context = HttpContext.Current;
return Task.Run(()=> { RequestHelper.SaveHttpContextInThread(context); return function(); } );
}
public static void SaveHttpContextInThread(HttpContext context)
{
Thread.SetData(Thread.GetNamedDataSlot(RequestHelper.THREAD_SLOT_NAME), context);
}
var response = TaskHelper.RunWithContext(() => _service.UpdateJob(jobjsonstring));
var jobData = JObject.Parse(response.Result); //Compiler error here
But a compiler error
'Argument 1: cannot convert from 'System.Threading.Tasks.Task'
to 'string'
occurs in the last line.
Seems to be an issue with the way I'm returning from the anonymous method.
Update
It seems _service.UpdateJob was returning Task but I was expecting it to return Job object, Apologies.
Actual Problem: In a WebAPI we want to run some task in a new thread. There is a value TransactionID in HttpContext.Items. We want the newly created thread to be able to read TransactionID. The above approach was to pass the entire HttpContext to the new thread.
It can get quite confusing with the nested use of tasks, especially without the use async/await.
The _service.UpdateJob(jobjsonstring) returns a Task. Therefore Task.Run which executes this function returns a Task object with a Task as result.
In order to get the Result of the _service.UpdateJob call you have to use response.Result.Result.
var jobData = JObject.Parse(response.Result.Result);
Another alternative (without async/await) is to return the Result inside the function, e.g.
var response = TaskHelper.RunWithContext(() => _service.UpdateJob(jobjsonstring).Result);
I have the method that takes an argument from external dll through a delegate pointer:
public delegate void NotificationsCallbackDelegate(CinectorNotification message);
NotificationsCallbackDelegate notificationsCallbackDeleg;
IntPtr notificationsCallbackPointer;
notificationsCallbackDeleg = NotificationsCallback;
notificationsCallbackPointer = Marshal.GetFunctionPointerForDelegate(notificationsCallbackDeleg);
instance.SetNotificationsCallback(notificationsCallbackPointer);
private void NotificationsCallback(CinectorNotification notif)
{
Log.AppendText("[" + notif.timestamp + "] " + notif.type + ": " + notif.message + Environment.NewLine);
}
So, input argument 'message' is something that can be passed by dll at any time during the application flow, whenever the external engine generates some log. It is like an event.
I use the following code to put a method on a new thread:
private void startNotifications()
{
Thread NotificationsThread = new Thread(new ThreadStart(NotificationsCallback));
NotificationsThread.IsBackground = true;
NotificationsThread.Start();
}
However, the method NotificationsCallback(CinectorNotification notif) takes in an argument and therefore doesn't match the delegate for ThreadStart. So how would I put a method like this on a different thread?
You can use Task.Run and supply it a lambda where you call NotificationsCallback with whatever arguments you need For example:
private void startNotifications()
{
Task.Run(() => NotificationsCallback(arg1, arg2) );
}
This will result in NotificationsCallback being run on on a ThreadPool thread.
For more information on Task.Run, see: https://msdn.microsoft.com/en-us/library/hh195051(v=vs.110).aspx
You code would work if there is a method passed in the parameter is parameterless.
If you want a parametrised thread, you should use another overload of the Thread constructor which will take ParameterizedThreadStart.
Start method on the thread is then called with an argument which is passed on to the thread method like this:
Thread thread = new Thread(WorkerMethod);
thread.Start(35); //for example 35
void WorkerMethod(object parameter)
{
int? intParameter = parameter as int?; //for example
if (intParameter.HasValue)
{
//do stuff
}
}
You can also use Task, which is a more modern approach to multi-threading.
Task.Factory.StartNew(() => WorkerMethod(35)); //for example 35
Or Task.Run in .NET 4.5 and newer. In task one can pass as many paramaters as wanted (without creating a container for them) and also the parameters can be strongly typed... not just object.
Instead of using ThreadStart you could use ParameterizedThreadStart and pass the required parameters in Thread.Start.
I have the following method, which I want to run using WaitCallBack delegate (C# Thread-Pooling) technique:
public void ExportData(string data){
//Codes goes in here
}
how to use ThreadPool.QueueUserWorkItem(new WaitCallback(ExportData),object}
in order to call this method??
The WaitCallback that this function expects takes an object state parameter. So you could do this:
string data = "some data";
ThreadPool.QueueUserWorkItem(state => ExportData((string)state), data);
or update the signature of your method:
public void ExportData(object state)
{
string data = (string)state;
//Codes goes in here
}
and then:
string data = "some data";
ThreadPool.QueueUserWorkItem(ExportData, data);
Some options:
Declare the method with type string and cast
Use a lambda expression instead, e.g.
ThreadPool.QueueUserWorkItem(ignored => ExportData(value))
where I assume value is a string variable in scope at the time. This will create a new delegate instance each time you go through this code, to capture value.
A combination of the above:
ThreadPool.QueueUserWorkItem(x => ExportData((string) x), value)
This will (potentially) reuse the same delegate instance on every call, as the value is passed via the normal WaitCallback instead of being captured by the delegate.
Additionally, you might want to consider using the rather more modern Task API unless you're targeting an old version of .NET. It's a generally more pleasant way of scheduling and managing tasks.
The following code compiles and runs well. But where is the return statement for the Consumer() and Producer() methods?
class Program
{
static BufferBlock<Int32> m_buffer = new BufferBlock<int>(
new DataflowBlockOptions { BoundedCapacity = 10 });
public static async Task Producer() <----- How is a Task object returned?
{
while (true)
{
await m_buffer.SendAsync<Int32>(DateTime.Now.Second);
Thread.Sleep(1000);
}
}
public static async Task Consumer() <----- How is a Task object returned?
{
while (true)
{
Int32 n = await m_buffer.ReceiveAsync<Int32>();
Console.WriteLine(n);
}
}
static void Main(string[] args)
{
Task.WaitAll(Consumer(), Producer());
}
}
While your question states the obvious - the code compiles - and the other answers try to explain-by-example, I think the answer is best described in the following two articles:
"Above-the-surface" answer - full article is here: http://msdn.microsoft.com/en-us/magazine/hh456401.aspx
[...] C# and Visual Basic [...] giving enough hints to the compilers
to build the necessary mechanisms for you behind the scenes. The
solution has two parts: one in the type system, and one in the
language.
The CLR 4 release defined the type Task [...] to represent the
concept of “some work that’s going to produce a result of type T in
the future.” The concept of “work that will complete in the future but
returns no result” is represented by the non-generic Task type.
Precisely how the result of type T is going to be produced in the
future is an implementation detail of a particular task; [...]
The language half of the solution is the new await keyword. A regular
method call means “remember what you’re doing, run this method until
it’s completely finished, and then pick up where you left off, now
knowing the result of the method.” An await expression, in contrast,
means “evaluate this expression to obtain an object representing work
that will in the future produce a result. Sign up the remainder of the
current method as the callback associated with the continuation of
that task. Once the task is produced and the callback is signed up,
immediately return control to my caller.”
2.The under-the-hood explanation is found here: http://msdn.microsoft.com/en-us/magazine/hh456403.aspx
[...] Visual Basic and C# [...] let you express discontinuous
sequential code. [...] When the Visual Basic or C# compiler gets hold
of an asynchronous method, it mangles it quite a bit during
compilation: the discontinuity of the method is not directly supported
by the underlying runtime and must be emulated by the compiler. So
instead of you having to pull the method apart into bits, the compiler
does it for you. [...]
The compiler turns your asynchronous method into a statemachine. The
state machine keeps track of where you are in the execution and what
your local state is. [...]
Asynchronous methods produce Tasks. More specifically, an asynchronous
method returns an instance of one of the types Task or Task from
System.Threading.Tasks, and that instance is automatically generated.
It doesn’t have to be (and can’t be) supplied by the user code. [...]
From the compiler’s point of view, producing Tasks is the easy part.
It relies on a framework-supplied notion of a Task builder, found in
System.Runtime.CompilerServices [...] The builder lets the compiler
obtain a Task, and then lets it complete the Task with a result or an
Exception. [...] Task builders are special helper types meant only for
compiler consumption. [...]
[...] build up a state machine around the production and consumption
of the Tasks. Essentially, all the user logic from the original method
is put into the resumption delegate, but the declarations of locals
are lifted out so they can survive multiple invocations. Furthermore,
a state variable is introduced to track how far things have gotten,
and the user logic in the resumption delegate is wrapped in a big
switch that looks at the state and jumps to a corresponding label. So
whenever resumption is called, it will jump right back to where it
left off the last time.
when the method has no return statement its return type is Task. Have a look at the MSDN page of Async Await
Async methods have three possible return types: Task<TResult>, Task, void
if you need a Task you must specify the return statement. Taken from the MSDN page:
// TASK<T> EXAMPLE
async Task<int> TaskOfT_MethodAsync()
{
// The body of the method is expected to contain an awaited asynchronous
// call.
// Task.FromResult is a placeholder for actual work that returns a string.
var today = await Task.FromResult<string>(DateTime.Now.DayOfWeek.ToString());
// The method then can process the result in some way.
int leisureHours;
if (today.First() == 'S')
leisureHours = 16;
else
leisureHours = 5;
// Because the return statement specifies an operand of type int, the
// method must have a return type of Task<int>.
return leisureHours;
}
async keyword kind of tells compiler that the method body should be used as a Task body. In simple way we can say that these are equivalents to your examples:
public static Task Producer() <----- How is a Task object returned?
{
return Task.Run(() =>
{
while (true)
{
m_buffer.SendAsync<Int32>(DateTime.Now.Second).Wait();
Thread.Sleep(1000);
}
});
}
public static Task Consumer() <----- How is a Task object returned?
{
return Task.Run(() =>
{
while (true)
{
Int32 n = m_buffer.ReceiveAsync<Int32>().Wait();
Console.WriteLine(n);
}
});
}
Of course the compiled result of your methods will be completely different from my examples, because compiler smart enough and it can generate code in such way, so some of the lines in your method will be invoked on the context (thread), which calls the method and some of them on the background context. And this is actually why Thread.Sleep(1000); is not recommended in the body of async methods, because this code can be invoked on the thread, which calls this method. Task has equivalent which can replace Thread.Sleep(1000); the equivalent await Task.Delay(1000), which will be invoked on background thread. As you can see await keyword guaranties you that this call will be invoked on the background context and will not block the caller context.
Let's take a look on one more example:
async Task Test1()
{
int a = 0; // Will be called on the called thread.
int b = await this.GetValueAsync(); // Will be called on background thread
int c = GetC(); // Method execution will come back to the called thread again on this line.
int d = await this.GetValueAsync(); // Going again to background thread
}
So we can say that this will be generated code:
Task Test1()
{
int a = 0; // Will be called on the called thread.
vat syncContext = Task.GetCurrentSynchronizationContext(); // This will help us go back to called thread
return Task.Run(() =>
{
// We already on background task, so we safe here to wait tasks
var bTask = this.GetValueAsync();
bTask.Wait();
int b = bTask.Result;
// syncContext helps us to invoke something on main thread
// because 'int c = 1;' probably was expected to be called on
// the caller thread
var cTask = Task.Run(() => return GetC(), syncContext);
cTask.Wait();
int c = cTask.Result;
// This one was with 'await' - calling without syncContext,
// not on the thread, which calls our method.
var dTask = this.GetValueAsync();
dTask.Wait();
int d = dTask.Result;
});
}
Again, this is not the same code which you will get from compiler, but it should just give you some idea how this works. If you really want to take a look on what will be in the produced library, use for example IlSpy to take a look on generated code.
Also I really recommend to read this article Best Practices in Asynchronous Programming
That's exactly what the async keyword means. It takes a method and (usually) converts it to a Task returning method. If the normal method would have the return type of void, the async method will have Task. If the return type would be some other T, the new return type will be Task<T>.
For example, to download an process some data synchronously, you could write something like:
Foo GetFoo()
{
string s = DownloadFoo();
Foo foo = ParseFoo(s);
return foo;
}
The asynchronous version would then look like this:
Task<Foo> GetFoo()
{
string s = await DownloadFoo();
Foo foo = ParseFoo(s);
return foo;
}
Notice that the return type changed from Foo to Task<Foo>, but you're still returning just Foo. And similarly with void-returning methods: since they don't have to contain a return statement, async Task (without any <T>) methods also don't.
The Task object is constructed by the compiler-generated code, so you don't have to do that.